0.JavaScript是脚本语言

概述

JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备

  • JavaScript 是一种轻量级的编程语言。
  • JavaScript 是可插入 HTML 页面的编程代码。
  • JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。
  • JavaScript 很容易学习。

1.JavaScript快速入门

1.1.引入JavaScript

1.1.1.script标签内编写⇒在head/body写均可

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Title</title>  
  
    <script>        
	    alert("hello world!");  
    </script>  
</head>  
<body>  
</body>  
</html>
 

1.1.2.外部引入⇒通过script标签引入.js文件(和css文件做区别,css使用link进行导入)

alert("hello world")
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Title</title>  
    <script src="../js/first.js"></script>  
</head>  
<body>  
</body>  
</html>

1.2.基本语法

绝大多数语法与Java类似,以下列出与Java不同的语句标识符

语句描述
function定义一个函数
var定义一个变量

1.2.1.变量

区别于Java,JavaScript中的变量统一以var来定义

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Title</title>  
    <script>        //1.定义变量  
        var num = 1;  
        var a = 2;  
        var b = 3;  
        alert(num)  
        //2.条件语句  (可嵌套)
        if (b > a){  
            alert("b大于a")  
        }  
    </script>  
</head>  
<body>  
  
</body>  
</html>
 

1.2.2.数据类型

JavaScript中的数据类型如下

类型关键字表示tips
数值Numberjs不区分小数 NAN(特殊:not a number)
动态类型var
布尔Booleantrue/false
字符串String通过单/双引号引起来
数组Array保证代码的可读性,建议使用[]
对象Object键值对通常写法为 name : value
空null
未定义undefined
1.2.2.1.字符串
  • 正常字符串用单/双引号包裹
  • 注意转义字符 \
\ '
\n
\t
\u4e2d   \u####  Unicode字符
\x4l  ASCII字符
  • 多行字符串编写
var msg = `hello  
world  
my  
name  
is  
Joe`
  • 模板字符串
let name = "Joe";  
let age = 18;  
let msg = `你好,${name}`
  • 字符串长度
str.length
  • 字符串可变性⇒不可变
  • 大小写转换
student.toUpperCase()
student.toLowerCase()
 
  • 获取索引
student.IndexOf('t')
  • 截取字符串
student.substring(1)   //从第一个字符串截取到最后一个
student.substring(1,3) //从第一个字符串截取到第二个
1.2.2.2.数组⇒Array(可以包含任意类型的数据)
var arr = [1,2,3,4,5,6]
  • 获取长度
arr.length
  • 获取元素索引
arr.indexOf(2)
1
  • 截取数组元素⇒包头不包尾,返回一个新数组
arr.slice(1,5)
  • push/pop
arr.push('a','b') //'a'和'b'被压入到尾部
arr.pop()  //'b'被弹出
  • unshift/shift
arr.unshift('c','d')   //在头部插入c和d两个字符
arr.unshift('c')       //弹出c
  • 排序
arr.sort()
  • 反转数组
arr.reverse()
  • 拼接⇒返回新数组,不修改原数组
["C","B","A"]
arr.concat([1,2,3])
  • 连接符join
["C","B","A"]
arr.join('-')
"C-B-A"
1.2.2.3.对象
  • 创建对象⇒用大括号括起来,键值对用冒号连接
var 对象名 = {
	对象属性名1 : 属性值1,
	对象属性名2 : 属性值2,
	对象属性名3 : 属性值3,
	对象属性名4 : 属性值4
}
var person = {
	name : "Joe",
	age : 18,
	score : 90
}
 
  • 对象赋值
person.name = "Jack"
"Jack"
  • 用不存在的对象属性不会报错⇒undefined
person.haha
"undefined"
  • 动态删减
delete person.name
true
person
  • 动态添加⇒直接为新属性赋值
person.haha = "haha"
  • 判断属性值是否在对象中
'age' in person
"true"
//继承
'toString' in person
"true"

判断一个属性是否是这个对象自身拥有的hasOwnProperty()

person.hasOwnProperty('toString')
"false"
person.hasOwnProperty('age')
"true"

1.2.3.运算符

1.2.3.1.算术运算符⇒同Java
1.2.3.2.赋值运算符⇒同Java
1.2.3.3.比较运算符
名称符号tips
等于==值相同但是类型不同,仍然返回true(不建议使用)
绝对等于===值和类型都相同,才会返回true.NaN与所有数值不相等
不等于!=同Java
严格不等于!==值和类型有一个不相等,或两个都不相等返回true
大于(等于)>/>=同Java
小于(等于)</⇐同Java

1.2.4.流程控制⇒分支/循环⇒同Java

//分支结构
var age = 3;  
if (age>3){  
    alert("haha");  
}  
else {  
    alert("kk")  
}
//循环结构
var age = 3;
while  (age<10){  
    alert("haha");  
    age++;  
}
//forEach方法
var arr = [1,2,3,4,5,6,7,8,9];
arr.forEach(function (item) {  
    console.log(item);  
})
//for...in 循环
for(var num in arr){  
    console.log(arr[num]);
}

1.2.5.Map(集合)和Set(无需不重复的集合)

1.2.5.1.Map
// var names = ["tom","joe","haha"]  
// var scores = [100 ,98 ,99]  
  //-->
var map = new Map([["tom",100],["joe",98],["haha",99]]);
//通过key 获得value
var name = map.get('tom');
console.log(name)
//添加/修改
map.set('admin',97)
//删除
map.delete("tom")
1.2.5.2.Set
//Set会去重
var set = new Set([3,1,1,1,1]);
"[3,1]" 
//添加元素
set.add(5);
"[3,1,5]"
//删除元素
set.delete(3);
"[1,5]"
//是否包含某个元素
console.log(set.has(5))
"true"
1.2.5.3.iterator迭代器⇒执行遍历操作
//通过for...of实现 ,for...in返回值是索引!
//遍历数组
var arr = [3,4,5]  
for(var x of arr){  
    console.log(x)  
}
//遍历Map
var map = new map(['a',1],['b',2],['c',4]);  
for(let x in map){  
    console.log(x);  
}
//遍历Set
var set = new Set([1,2,3,4]);  
for(let x of set){  
    console.log(x);  
}

1.3.函数与面向对象

方法: 对象(属性,方法)

1.3.1.函数的定义与变量作用域

1.3.1.1.定义一个函数⇒关键字:function
//定义方法1:
//定义一个绝对值函数
function abs(x){
	//手动抛出异常  
	if(typeof x !== 'number'){  
	    throw new Error('参数必须为数字');  
	}
	if(x>=0){
		return x;
	}
	else{
		return -x;
	}
}
//定义方法2:
var abs = function(x){
	if(x>=0){
		return x;
	}
	else{
		return -x;
	}
}

调用函数 参数问题:JavaScript可以传任意个参数,也可以不传递参数

//调用函数
abs(10) //10
abs(-10) //10
abs(10,20,30) //10
 
arguments

arguments是一个JS免费赠送的关键字,代表传递进来的所有参数,形式为一个数组.但是,arguments包含所有参数,有时候想使用多余的参数进行附加操作,需要排除已有的参数

function abs(x){  
    console.log("x=>"+ x);  
    for(var i =0 ; i < arguments.length; i++){  
        console.log(arguments[i]);  
    }  
    if(x>=0){  
        return x;  
    }else{  
        return -x;  
    }  
}
rest

ES6引入的新特性,获取除了已经定义的参数之外的所有参数,以数组的形式输出

//rest参数只能写在最后面,用...标识
function aaa(a,b,...rest){  
    console.log("a=>"+b);  
    console.log("b=>"+b);  
    console.log(rest);  
    if(arguments.length > 2){  
        for(var i = 2 ; i<=arguments.length; i++){  
            console.log(arguments[i]);  
        }  
    }  
}
1.3.1.2.变量作用域
  • JavaScript的变量生命周期在声明时初始化,局部变量在函数执行完毕后销毁,全局变量在页面关闭后销毁
  • 假设在函数体内声明,则在函数体外不可使用
  • 如果两个函数使用相同的变量名,只要在函数内部,就不冲突
  • JavaScript中只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数的作用范围内找到,就会向外查找,如果在全局作用域内也没找到,就会报错(RefrenceError—引用异常)
function h(){  
    var x = 1;  
    x++;  
}  
// x+=2 -->报错:变量未定义
function g(){  
    var x = 1;  
    x++;  
}
  • 内部函数可以访问外部函数成员,反之不行
//内部函数可以访问外部函数成员,反之不行
function f(){  
    var x = 1;;  
    function f1(){  
        var y = x+1;  
    }  
    var z = y-1; //  变量未定义  
}
  • 假设在JavaScript中函数查找变量从自身函数开始,由内向外查找. 假设内部函数的变量和外部函数的变量重名,内部变量的优先级最高(内部函数会屏蔽外部函数的变量)
//内外部变量重名,  函数内部变量优先级高
function fun1(){  
    var x = "A";  
    function fun2(){  
        var x = 114514;  
        console.log(x); //-->  114514  
    }  
    console.log(x);     //-->  A  
}

在函数中定义变量尽量放到函数代码块的最前面,便于维护!

  • 全局函数
var a = 1;  //默认全局变量都会绑定在window对象下
function f(){  
    console.log(a);  
}  
f();  
console.log(a)
  • 用关键字const定义常量(ES6之前用大写字母定义常量, ES6之后使用const关键字定义)
const PI = 3.1415926
  • 全局变量
//唯一全局变量
var Hu = {};
//定义全局变量
Hu.name = "hyy";
Hu.add = function(a,b){
	return a+b;
}

局部作用域⇒let关键字(ES6添加)

function aaa(){
	for(var i = 0 ; i<100 ; i++){
		console.log(i);
	}
	console.log(i+1); //问题:i出了作用域还能作用
}
 
//解决方案-->将var换成let
function aaa(){
	for(let i = 0 ; i<100 ; i++){
		console.log(i);
	}
	console.log(i+1); //问题:i出了作用域还能作用
}

1.3.2.方法

  • 方法就是把函数定义在对象的里面, 对象只有两个东西: 属性和方法
  • 调用方法时需要带括号⇒hu.age() ⇒19
var hu = {  
    name : "hyy",  
    birth : 2006,  
    //方法  
    age : function (){  
        var now = new Date().getFullYear();  
        return now-this.birth;  //this无法指向,默认指向调用它的对象
    }  
}
  • 在JavaScript中,可以控制this的指向(apply)
function getAge(){  
    var now = new Date().getFullYear();  
    return now-this.birth;  
}  
var hu = {  
    name : "hyy",  
    birth : 2006,  
    age : getAge()  
    
}  
var xiaoming = {  
    name : "小明",  
    birth : 2006,  
    age : getAge()  
    
}  
//this指向了hu这个对象
getAge.apply(hu,[]);

1.3.3.闭包(难点)

1.3.4.箭头函数

1.3.5.创建对象

在JavaScript中, 一切皆为对象,任何js支持的类型都可以用JSON表示 格式:

  • 对象都用{}
  • 数组都用[]
  • 所有的键值对表示都是 key : value
var user = {  
    name: "hyy",  
    age: 18,  
    sex: "男"  
};

1.3.6.原型链继承

原型(Prototype)是JavaScript中每个对象都具有的属性,它包含对象的共享属性和方法。当我们创建一个新对象时,这个对象会从原型继承属性和方法。原型链(Prototype Chain)是由对象组成的链式结构,它用于查找对象的属性和方法。当我们访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript引擎会沿着原型链向上查找,直到找到匹配的属性或方法

var student = {  
    name: '张三',  
    age: 18,  
    sex: '男',  
    run : function (){  
        console.log(this.name+"在运动");  
    }  
};  
  
var xiaoming = {  
    name: '小明'  
};  
  
xiaoming.__proto__ = student;

1.3.7.class继承(ES6引入)⇒与Java中的操作类似

function Person(name,age){  
    this.name = name;  
    this.age = age;  
}  
  
//给person新添加方法-->prototype找到原型  
Person.prototype.hello = function(){  
    console.log("hello"+this.name);  
}  
  
//ES6 之后  
class Student{  
	//构造器-->constructor
    constructor(name,age) {  
        this.name = name;  
        this.age = age;  
    }  
	hello(){  
	    console.log("hello"+this.name);  
	}
}
var xiaoming = new Student("xiaoming",18);
 
class PrimaryStudent extends Student{  
    constructor(name,age,grade){  
        super(name,age);  
        this.grade = grade;  
    }  
    myGrade(){  
        console.log("这是我的年级"+this.grade);  
    }  
}

2.JavaScript进阶

2.1.常用对象

2.1.1.Date

定义

var now = new Date();  
now.getFullYear();      //年份  
now.getMonth();         //月份  
now.getDate();          //日期  
now.getDay();           //星期几  
now.getHours();         //时  
now.getMinutes();       //分  
now.getSeconds();       //秒  
now.getMilliseconds();  //毫秒  
now.getTime();          //时间戳-->距1970年1月1日 00:00:00 GMT+0800 (中国标准时间)的毫秒数
console.log(new Date())

转换

now.toLocaleString()
now.toGMTString()

2.1.2.JSON⇒轻量级的数据交换格式

  • JSON: JavaScript Object Notation(JavaScript 对象表示法)
  • JSON 是存储和交换文本信息的语法,类似 XML。
  • JSON 比 XML 更小、更快,更易解析。
  • JSON 易于人阅读和编写。
var user = {  
    name: "hyy",  
    age: 18,  
    sex: "男"  
};  
//对象转json字符串  
var json_user = JSON.stringify(user)    //stringify()转换为字符串  
//json字符串转对象,参数为json字符串  
var user_json = JSON.parse(json_user)   //parse()解析json转换为对象

2.2.操作DOM对象⇒文档对象模型(重点)

核心⇒整个浏览器网页就是一个DOM树形结构

要操作一个DOM结点,首先需要获取到这个结点

2.2.0.获取DOM结点(原生代码,后续使用jQuery)

<body>  
<div id="father">  
    <h1>标题1</h1>  
    <p id="p1">p1</p>  
    <p class="p2">p2</p>  
</div>  
  
  
<script>  
    //对应CSS中的选择器  
    var h1 = document.getElementsByTagName('h1')  
    var p1 = document.getElementById('p1')  
    var p2 = document.getElementsByClassName('p2')  
    var father = document.getElementById('father')  
    var children = father.children; //获取子元素  
</script>  
</body>

2.2.1.更新DOM

var id1 = document.getElementById(id1);  
id1.innerText =  "hello world";  
id1.style.color = "red";  
id1.style.fontSize = "20px";  
id1.style.backgroundColor = "yellow";  
id1.style.textAlign = "center";  
id1.style.margin = "auto";  
id1.style.width = "100px";  
id1.style.height = "100px";  
id1.style.border = "1px solid red";  
id1.style.display = "block";  
id1.style.position = "absolute";  
id1.style.left = "50%";  
id1.style.top = "50%";  
id1.style.transform = "translate(-50%,-50%)";  
id1.style.transition = "all 1s";

2.2.2.插入DOM

获得了某个DOM结点,假设这个结点是空的,通过innerHTML即可增加一个元素,但是如果结点非空, 如果再重复上述操作,就会覆盖掉原来的内容

  • 追加
var JS = document.getElementById('JS'),  
    list = document.getElementById('list');
 
list.appendChild(JS)
  • 创建新标签
// 创建元素  
var newP = document.createElement('p');  
newP.id = 'newP';  
newP.style.color = 'red';  
newP.style.background = 'blue';  
newP.innerText = 'hello world'  
  
//创建一个标签结点  
var myScript = document.createElement('script');  
myScript.setAttribute('type' , 'text/javascript');  
var body = document.getElementsByTagName('body');  
body[0].style.background = 'green';  
list.appendChild(newP);  
list.append(myScript);

2.2.3.删除DOM

  1. 先获取父结点
  2. 通过父结点删除自己
<div id="father">  
    <h1>标题1</h1>  
    <p id="p1">p1</p>  
    <p class="p2">p2</p>  
</div>  
  
  
<script>  
    //对应CSS中的选择器  
    var self = document.getElementById('p1');
    var father = p1.parentElement;
    father.removeChild(p1);
</script>

注: 删除是一个动态的过程,删除第一个元素后,第二个元素变成了第一个元素.即child属性是时刻变化的

2.3.操作BOM元素⇒浏览器对象模型(重点)

2.3.1.window→浏览器窗口

window.alert("hello world");  
window.confirm("hello world");  
window.innerHeight;  
window.innerWidth;  
window.outerHeight;  
window.outerWidth;

2.3.2.navigator⇒封装了浏览器信息(大多数时候不会使用)

window.navigator.geolocation.getCurrentPosition(function (position) {  
    console.log(position);  
});

2.3.3.screen⇒控制屏幕大小(单位:px)

screen.width = 1920;  
screen.height = 1080;

2.2.4.location⇒代表当前页面的URL信息(重要)

 
host: "nuc.alphacoding.cn"
 
href: "https://nuc.alphacoding.cn/home?1749970612859"
protocol: "https:"
 

2.2.5.Document⇒当前页面信息

document.title
'“学·练·测·考·评”智适应教学平台'
 
<body>  
<dl id="dl">  
    <dt>Java</dt>  
    <dd>JavaSE</dd>  
    <dd>JavaEE</dd>  
</dl>  
<script>  
    var dl = document.getElementById("dl"); //获取dl节点  
    var dt = dl.firstElementChild;  
    var dd = dt.nextElementSibling;  
    console.log(dd);  
</script>  
</body>
 

2.2.6.History⇒历史浏览记录

history.back();   //后退
history.forward();//前进

2.2.7.操作表单(验证)

  • 文本框 ⇒text
  • 下拉框 ⇒< select >
  • 单选框 ⇒radio
  • 复选框 ⇒checkbox
  • 隐藏域 ⇒hidden
  • 密码框 ⇒password
<body>  
<form action="post">  
    <p>        <span>用户名:</span><input type="text" id="username">  
    </p>    <p>        <span>性别:</span>  
        <input type="radio" value="male" name="sex" id="boy">男  
        <input type="radio" value="female" name="sex" id="girl">女  
    </p>  
</form>  
  
<script>  
    var input_text = document.getElementById("username");  
    var boy_radio = document.getElementById("boy");  
    var girl_radio = document.getElementById("girl");  
  
    //得到输入框的值  
    input_text.value;  
    //修改输入框的值  
    input_text.value = "hello world";  
  
</script>  
</body>

提交表单

<!DOCTYPE html>  
<html lang="zh-CN">  
<head>  
  <meta charset="UTF-8">  
  <title>简单表单验证</title>  
</head>  
<body>  
<h2>兴趣选择</h2>  
<form id="simpleForm">  
  <!-- 文本输入验证 -->  
  <div>  
    <label for="name">姓名(必填):</label>  
    <input type="text" id="name" name="name">  
    <span id="nameError" style="color:red;"></span>  
  </div>  
  <!-- 单选按钮验证 -->  
  <div>  
    <p>性别(必选):</p>  
    <input type="radio" id="male" name="gender" value="male">  
    <label for="male">男</label>  
  
    <input type="radio" id="female" name="gender" value="female">  
    <label for="female">女</label>  
  
    <span id="genderError" style="color:red;"></span>  
  </div>  
  <!-- 复选框验证(至少选2项) -->  
  <div>  
    <p>兴趣爱好(至少选2项):</p>  
    <input type="checkbox" id="sports" name="interests" value="sports">  
    <label for="sports">运动</label>  
  
    <input type="checkbox" id="music" name="interests" value="music">  
    <label for="music">音乐</label>  
  
    <input type="checkbox" id="reading" name="interests" value="reading">  
    <label for="reading">阅读</label>  
  
    <span id="interestsError" style="color:red;"></span>  
  </div>  
  <button type="submit">提交</button>  
</form>  
  
<script>  
  document.getElementById('simpleForm').addEventListener('submit', function(event) {  
    event.preventDefault();  
  
    // 清除之前的错误信息  
    document.getElementById('nameError').textContent = '';  
    document.getElementById('genderError').textContent = '';  
    document.getElementById('interestsError').textContent = '';  
  
    // 验证姓名(必填)  
    const name = document.getElementById('name').value.trim();  
    if (name === '') {  
      document.getElementById('nameError').textContent = '请输入姓名';  
      return false;  
    }  
  
    // 验证性别(必选)  
    const genderSelected = document.querySelector('input[name="gender"]:checked');  
    if (!genderSelected) {  
      document.getElementById('genderError').textContent = '请选择性别';  
      return false;  
    }  
  
    // 验证兴趣爱好(至少选2项)  
    const checkedInterests = document.querySelectorAll('input[name="interests"]:checked');  
    if (checkedInterests.length < 2) {  
      document.getElementById('interestsError').textContent = '请至少选择2项兴趣爱好';  
      return false;  
    }  
  
    // 所有验证通过  
    alert('表单验证通过!\n姓名: ' + name +  
            '\n性别: ' + genderSelected.value +  
            '\n兴趣: ' + Array.from(checkedInterests).map(c => c.value).join(', '));  
  
  
    this.submit();  
  });  
</script>  
</body>  
</html>