一、ECMAScript与JavaScript 的关系
前者是后者的规格,后者是前者的一种实现。在日常场合,这两个词是可以互换的。
二、let和const命令
1、let与var
var:变量提升 与 let:块级作用域
<script> console.log(a) //输出结果: undefined console.log(b) //直接报错: Uncaught ReferenceError: Cannot access 'b' before initialization var a = "Hello,World"; let b ="Hello,ECMA6" </script>
<script> { var a = "Hello,World"; let b = "Hello,ECMA6" } console.log(a) //输出结果: Hello,World console.log(b) //直接报错: Uncaught ReferenceError: b is not defined </script>
{ var a = "Hello,World" var a = "Hello,ECMA6" console.log(a) //输出结果: Hello,ECMA6 }
{ let b = "Hello,World"; let b = "Hello,ECMA6" console.log(b) //报错:Uncaught SyntaxError: Identifier 'b' has already been declared }
let n=5 if(true){ let n =10; } console.log(n) //输出结果: 5
<script> var a=[] for (let i = 0; i < 5; i++) { a[i]=function () { console.log(i) } } var b=[] for (var i = 0; i < 5; i++) { b[i]=function () { console.log(i) } } a[0]() //0 b[0]() //5 </script>
2、const
- 没有变量提升(与let类似)
- 同样存在块级作用域(与let类似)
- 不能重复定义(与let类似)
- 定义时候必须赋值
- 定义之后不能修改
<script> var a; let b; // const C; //直接报错:Missing initializer in const declaration const C = 3.1415; //C = 4; //直接报错: Uncaught TypeError: Assignment to constant variable. // const C = 5;//直接报错: Uncaught SyntaxError: Identifier 'C' has already been declared console.log(a, b, C) //输出结果:undefined undefined 3.1415 </script>
三、变量的解构赋值
解构(Destructuring):从数组和对象中提取值,对变量进行赋值
1:数组解构
<script> //--------数组解构------------ var [x, y, z] = [1, 2, 3] let [x1, y1, z1] = [1, 2, 3] const [x11, y11, z11] = [1, 2, 3] console.log(x, y, z) //输出结果:1 2 3 一一对应解构 console.log(x1, y1, z1) //输出结果:1 2 3 一一对应解构 console.log(x11, y11, z11) //输出结果:1 2 3 一一对应解构 var [, , a] = [1, 2, 3] console.log(a)//输出结果:3 可以选择性解构 var [b, ...c] = [1, 2, 3] console.log(b, c)//输出结果:1 [2,3] rest参数解构 var [d,[[e,f]]] = [1, [[2, 3]]] console.log(d,e,f)//输出结果: 1 2 3 深层次解构 var [g] = [] console.log(g)//输出结果:undefined var [h=1] = [] console.log(h)//输出结果:1 默认值解构 // var [i]=undefined; //直接报错:undefined is not iterable var m=1,n=2; [m,n]=[n,m] console.log(m,n) //输出结果:2 1 可用于交换两个对象的值 </script>
- 解构只能用于数组或对象。
- 其他原始类型的值(1,'字符串',false,NaN)都可以转换成相应的对象,但是解析不会成功,结果为:undefined
- undefined和null不能转为对象,解构会报错。var[x]=null;报错
- 可以深层次解构数组
- 解构赋值允许指定默认值
- 解构赋值不仅适用于var,也适用于let和const
- 数组解构可用于交换两个变量值。[y,x]=[x,y]
2:扩展运算符
<script> Math.max(...[123, 222, 321, 5]) //等同于 Math.max(123,222,321,5) function add(x, y, z) { return x + y + z; } console.log(add(...[10, 20, 30])) //输出结果:60 </script>
- 标识符是三个点(...)
- rest参数逆运算,将数组转换为逗号分隔的参数序列
3:对象解构
<script> var {x, h, y} = {x: 10, y: 20, z: 30} console.log(x, y, h) //输出结果:10 20 undefined var {x, h=0, y} = {x: 10, y: 20, z: 30} console.log(x, y, h) //输出结果:10 20 0 var {x,y:[{z}]} = {x: 10, y:[{z: 30}] } console.log(x, z) //输出结果:10 30 //嵌套解构 var x; // {x}={x:100} //直接报错 Unexpected token '=' var x2; ({x2}={x2:100}) console.log(x2) //输出结果:100 </script>
- 变量必须与属性同名,等号两边次序可以不一致
- 解构同样可以用于嵌套对象
- 对象解构也可以指定默认值
- 将已经声明的变量用于解构赋值,需要格外小心。注意避免js将{}解释为代码块。
四、字符串
1:模板字符串
<script> var str1 = `可以当做普通字符串使用` var str2 = ` 第一行文本 第二行文本 ` var x = 1; var y = 2; var str3 = `${x}+${y}=${x + y}` console.log(str1) //输出结果:可以当做普通字符串使用 console.log(str2) //输出结果: /* 第一行文本 第二行文本 */ console.log(str3) //输出结果:1+2=3 </script>
- 用反引号(`)表示
- 可以当做普通字符串使用
- 可以用来定义多行字符串
- 可以在字符串中嵌入标量,需要将变量名写在${}
五、函數
1:默认值函数
//-----------默认值函数------------------ function add(x = 0, y = 0) { return x + y; } ret = add(10, 20) ret2 = add(30) ret3 = add(0, 0) console.log(ret, ret2, ret3) //输出结果:30 30 0
//----------利用参数默认值,可以指定某一个参数不得省略(一道面试题)------------------ function throwIfMissing() { throw new Error("缺少参数!") } function foo(mustBeProvided = throwIfMissing()) { return mustBeProvided; } // foo() //直接报错: Uncaught Error: 缺少参数
2:函数可以New
//-----------函数可以new------------------ function Point(x = 0, y = 0) { this.x = x; this.y = y; } var point = new Point(10) console.log(point) //输出结果:Point {x: 10, y: 0}
3:箭头函数
//----------箭头函数(相当于简写了{ return })---------------------- var f = v => v; //等价于:var f = function(v){return v;} //不带参数,或者多个参数,就使用一对圆括号代表参数部分 var f2 = () => "Hello,World!";//等价于:var f2 = function(){return "Hello,World!";} var f3 = (n1, n2) => n1 + n2; //等价于:var f = function(n1,n2){return n1+n2;} //代码块部分多余一条语句,就要使用{ return } var f4 = (n1, n2) =>{n1=n1+1;n2=n2+2;return n1+n2}; //如果返回的是对象,必须在对象外面加() var f5= (x, y) =>({"x":x,"y":y}); console.log(f(5),f2(),f3(10,20),f4(10,20)) //输出结果:5 "Hello,World!" 30
//-----------箭头函数 与 this--------------------- function func() { console.log(this) } var gunc = () => console.log(this) var obj={ func:func, gunc:gunc } func(); //输出结果:Window gunc(); //输出结果:Window obj.func() //输出结果:obj 使用时所在对象 obj.gunc() //输出结果:Window 定义时所在对象
- 箭头函数体内的this对象,绑定定义时所在的对象,而不是使用定义时所在的对象
- 不可以当做构造函数,也就是说,不可以使用new命令
- 不可以使用arguments对象,该对象在函数体内不存在
4:单体函数
//-----------单体函数 --------------------- let obje={ name:'单体函数', foo(){ console.log(this.name) } } obje.foo() //输出结果:单体函数
5:rest参数(...变量名)
// rest参数 function add(...args) { let sum = 0; for (var i of args) { sum += i; } return sum; } console.log(add(1, 2, 3, 4)) function add2(x = 0, y = 0, ...kwargs) { let sum = x + y; for (var z of kwargs) { sum += z; } return sum; } console.log(add2(x = 1, y = 2, m = 3, n = 4))
- 类似Python中的*args
- rest参数后面不能再有其他参数
六、类
1:类
class Point { //构造函数, //this关键字表示实例对象 constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ',' + this.y + ')'; } } //必须使用new来实例化 var point = new Point(3, 4) console.log(point.toString()) //输出结果:(3,4)
-
constructor 构造函数
-
必须使用new来实例化
2:继承
<script> class Point { //构造函数, //this关键字表示实例对象 constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ',' + this.y + ')'; } } //必须使用new来实例化 var point = new Point(3, 4) console.log(point.toString()) //输出结果:(3,4) class ColorPoint extends Point { constructor(x, y, color) { super(x, y) this.color = color; } toString() { return this.color + "" + super.toString(); } } var colorpoint = new ColorPoint(1, 2, 'red') console.log(colorpoint.toString()) //输出结果:red(1,2) </script>