对象方法中的super
原型对于javascript来说非常重要,甚至可以说是javascript中最为重要的知识点。然而,很多人一看到原型就懵逼。ES5我们可以使用Object.getPrototypeOf()来返回原型对象,使用Object.setPrototypeOf()来设置原型对象。 看下面的例子:
1let person = { 2 getSay() { 3 return 'hello' 4 } 5} 6 7let tom = { 8 getSay() { 9 return Object.getPrototypeOf(this).getSay.call(this) + ',jack' 10 } 11} 12 13Object.setPrototypeOf(tom, person); 14console.log(tom.getSay()) // hello,jack
以上代码通过 Object.setPrototypeOf(tom, person) 设置tom的原型对象为person,通过Object.getPrototypeOf(this)返回tom的原型对象person,所以Object.getPrototypeOf(this).getSay 实际上就是person.getSay,在通过call()方法将peoson中的this指向tom作用域,实现tom继承peoson。
相信很多人在看到Object.getPrototypeOf()和call()来调用原型时已经由懵逼遍傻逼的了。好在ES6中引入了super关键字来解除我们的痛苦。super引用相当于指向原型对象的指针,实际上也就是Object.getPrototypeOf(this)的值。废话少说,我们将上面的例子改变以下:
1let person = { 2 getSay() { 3 return 'hello' 4 } 5} 6 7let tom = { 8 getSay() { 9 // 相当于Object.getPrototypeOf(this).getSay.call(this) 10 return super.getSay() + ',jack'; 11 } 12} 13 14Object.setPrototypeOf(tom, person); 15console.log(tom.getSay()); // hello,jack
怎么样,是不是感觉爽了很多。不过得注意,super只能在简写的对象方法中使用。可是还有同学说我看到Object.setPrototypeOf(tom, person)我也恶心,别急,ES6都为你准备好了,请继续往下看。
class中的super
在ES6之前,javascript都不支持类的概念,开发者都是通过原型实现类似类的结构。
ES5中,我们通过在继承的函数中调用call()或者apply()方法实现继承。
1function SuperType(name) { 2 this.name = name; 3 this.color = ["red", "blue"]; 4} 5SuperType.prototype.sayName = function() { 6 alert(this.name); 7} 8function SubType(name, age) { 9 SuperType.call(this, name); 10 this.age = age; 11} 12SubType.prototype = new SuperType(); 13SubType.prototype.constructor = SubType; 14 15var s1 = new SubType('ren'); 16s1.sayName(); 17console.log(s1.color); // ["red", "blue"]
ES6中我们可以通过类,我们使用extends实现基类(SuperType)与派生类(SubType)之间的继承。在派生类的constructor中调用super()即可访问基类的构造函数。super()负责初始化this,相当于ES5中的call和apply方法。
1class SuperType { 2 constructor(name) { 3 this.name = name; 4 this.color = ["red", "blue"]; 5 } 6 sayName() { 7 alert(this.name); 8 } 9} 10class SubType extends SuperType { 11 constructor(name, age) { 12 // 相当于SuperType.call(this, name); 13 super(name); 14 this.age = age; 15 } 16} 17var s1 = new SubType('ren', 19); 18s1.sayName(); 19console.log(s1.color); // ["red", "blue"]
Tips:
1- 只可在派生类的构造函数中使用super() 2- 在构造函数中访问this之前一定要调用super(),它负责初始化this。