js中的super小結

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也是personui

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指向的仍是manthis

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 對象spa

super()至關於Parent.prototype.constructor.call(this)prototype

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對象code

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 在靜態方法之中指向父類,在普通方法之中指向父類的原型對象get

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
複製代碼
相關文章
相關標籤/搜索