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對象。
ES6 規定,在子類普通方法中通過super
調用父類的方法時,方法內部的this
指向當前的子類實例。
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
---------------------
作者:TianyuCool
來源:CSDN
原文:https://blog.csdn.net/qq_35087256/article/details/82669618