ES6相关
let、const与var相比
使用未声明的变量,直接报错
重复声明同一个变量,直接报错
是块级作用域
必须声明 ‘use strict’ 后才能使用let声明变量数组的解构赋值,是值的拷贝,不是深拷贝
- 对象的解构赋值,是值的拷贝,不是深拷贝,let {a: { b }} = {a: { b: 1 }} 给b赋值,此时a是未定义的
箭头函数
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是不可以使用new命令,否则会抛出错误。
(3)不可以使用arguments对象,该对象在函数体内不存在,如果要用,可以使用rest参数代替。
(4)不可以使用yield命令,因为箭头函数不能用作Generator函数。理解定义时所在的作用域。
12345678910111213141516171819202122232425262728293031var obj = {a: 1,fn: function () {console.log(this.a)}};obj.fn(); // 1var obj = {a: 1,fn: () => {console.log(this.a)}};obj.fn(); // undefinedvar obj = {a: 1,fn: function () {setTimeout(() => {console.log(this.a)}, 0)}};obj.fn(); // 1var obj = {a: 1,fn: function () {console.log(this.a)}};setTimeout(obj.fn, 0); // undefinedvar obj = {a: 1,fn: () => {console.log(this.a)}};setTimeout(obj.fn, 0); // undefinedsuper
super关键字,既可以当作函数使用,也可以当作对象使用。使用super的时候,必须显式指定是作为函数、还是作为对象使用,否则会报错。由于对象总是继承其他对象的,所以可以在任意一个对象中,使用super关键字。
12345678910111213141516171819202122class A {}class B extends A {constructor() {super();/*Uncaught SyntaxError: 'super' keyword unexpected here无法看出super是作为函数使用,还是作为对象使用*/console.log(super);/*super.valueOf()表明super是一个对象*/console.log(super.valueOf() instanceof B); // true}}var obj = {toString() {return "MyObject: " + super.toString();}};obj.toString(); // MyObject: [object Object]第一种情况,当作函数使用,代表父类的构造函数,super虽然代表了父类的构造函数,但是返回的是子类的实例,即super内部的this指的是子类。super()只能用在子类的构造函数中,用在其它地方就会报错。ES6要求,子类的构造函数必须执行一次super函数。
12345678910class A{}class B extends A {constructor() {/*当作函数使用,代表父类的构造函数,相当于A.prototype.constructor.call(this)*/super();}}第二种情况,super作为对象时,在普通方法中指向父类的原型对象,在静态方法中指向父类。ES6规定,通过super调用父类的方法时,super会绑定子类的this。由于绑定子类的this,所以如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性。
123456789101112131415161718192021222324252627282930313233class A {constructor() {this.q = 2;}p() {return 2;}print() {/*通过B的super.print()虽然调用的是A.prototype.print(),但是A.prototype.print()会绑定子类B的this,相当于super.print.call(this)*/console.log(this.q);}}class B extends A {constructor() {super();this.q = 3;/*当作对象使用,这是普通方法,super指向A.prototype,相当于A.prototype.p()q是父类A实例的属性,super.q就引用不到它*/console.log(super.p()); // 2console.log(super.q); // undefined}subPrint() {super.print();}}let b = new B();b.subPrint(); // 31234567891011121314151617181920212223class Parent {static myMethod(msg) {console.log('static', msg);}myMethod(msg) {console.log('instance', msg);}}class Child extends Parent {static myMethod(msg) {// 静态方法,super指向父类super.myMethod(msg);}myMethod(msg) {// 普通方法,super指向父类的原型对象super.myMethod(msg);}}Child.myMethod(1); // static 1var child = new Child();child.myMethod(2); // instance 2