1.this和super的区别:
this关键词指向函数所在的当前对象
super指向的是当前对象的原型对象
2.super的简单应用
const person = { name:'jack' } const man = { sayName(){ return super.name; } } Object.setPrototypeOf( man, person ); let n = man.sayName(); console.log( n )//jack
3.super的另类实现
super.name
等同于
Object.getPrototypeOf(this).name【属性】
等同于
Object.getPrototypeOf(this).name.call(this)【方法】
4.super中的this指向(易混淆)
super.name指向的是原型对象person 中的name,但是绑定的this还是当前的man对象。
const person = { age:'20多了', name(){ return this.age; } } const man = { age:'18岁了', sayName(){ return super.name(); } } Object.setPrototypeOf( man, person ); let n = man.sayName(); console.log( n )//18岁了
Object.getPrototypeOf(this).name指向的是person的name,绑定的this也是person
const person = { age:'20多了', name(){ return this.age; } } const man = { age:'18岁了', sayName(){ return Object.getPrototypeOf(this).name(); } } Object.setPrototypeOf( man, person ); let n = man.sayName(); console.log( n )//20多了
Object.getPrototypeOf(this).name.call(this)指向的是person的name,不过通过call改变了函数的执行上下文,所以this指向的还是man
const person = { age:'20多了', name(){ return this.age; } } const man = { age:'18岁了', sayName(){ return Object.getPrototypeOf(this).name.call(this) } } Object.setPrototypeOf( man, person ); let n = man.sayName(); console.log( n ) //18岁了
4.Class中的super
(1)Class中的 super(),它在这里表示父类的构造函数,用来新建父类的 this 对象
super()相当于Parent.prototype.constructor.call(this)
class Demo{ constructor(x,y) { this.x = x; this.y = y; } customSplit(){ return [...this.y] } } class Demo2 extends Demo{ constructor(x,y){ super(x,y); } customSplit(){ return [...this.x] } task1(){ return super.customSplit(); } task2(){ return this.customSplit(); } } let d = new Demo2('hello','world'); d.task1() //["w", "o", "r", "l", "d"] d.task2() //["h", "e", "l", "l", "o"]
(2)子类没有自己的this对象,而是继承父亲的this对象,然后进行加工。如果不调用super,子类就得不到this对象
class Demo2 extends Demo{ constructor(x,y){ this.x = x; //this is not defined } }
ES5的继承,实质上是先创造子类的实例对象this,然后再将父类的方法添加到this上(Parent.call(this))。
ES6的继承,需要先创建父类的this,子类调用super继承父类的this对象,然后再加工。
如果子类没有创建constructor,这个方法会被默认添加:
class Demo{ constructor(x) { this.x = x; } } class Demo2 extends Demo{} let d = new Demo2('hello'); d.x //hello
(3)super 在静态方法之中指向父类,在普通方法之中指向父类的原型对象
class Parent { static myMethod(msg) { console.log('static', msg); } myMethod(msg) { console.log('instance', msg); } } class Child extends Parent { static myMethod(msg) { super.myMethod(msg); } myMethod(msg) { super.myMethod(msg); } } Child.myMethod(1); // static 1 var child = new Child(); child.myMethod(2); // instance 2