es5與es6繼承思考

es5與es6繼承思考


es6繼承

class Father{
  constructor(name){
    this.name = name;
  }
  getName(){
    console.log(this.name);
  }
  //  這裏是父類的f方法
  f(){
    console.log('fffffffffffffffffffffff');
  }
}
class Son extends Father{
  constructor(name,age){
    super(name); // HACK: 這裏super()要在第一行
    this.age = age;
  }
  getAge(){
    console.log(this.age);
  }
  //  子類的f方法
  f(){
    console.log('sssssssssssssssssssssss');
  }
}
var s1 = new Son('張一',12);
s1.getName();
s1.getAge();
console.log(s1.__proto__); //  爲Son,不用修正
s1.f(); //  打印ssssssssssssss
s1.__proto__ = new Father();  //  改變s1的原型指向,改成Father
s1.f();  // 打印ffffffffffffff
console.log(s1.__proto__);  // 爲Father

__proto__

javascript給對象提供了一個__proto__的隱藏屬性,某個對象的__proto__屬性默認會指向它的構造器的原型對象.
這個是被實例化後的某個具體的對象纔有的屬性,是個指向。

prototype

這裏prototype是個對象
  在es5中能夠藉助ClassMy.prototype.fn = function(){}來對類進行添加能夠被全部子類繼承的方法。
  我在es6中基本沒用到這個屬性。

es5繼承

function Father(name){
  this.name = name;
}
function Son(name,age){
  Father.call(this,name);
  this.age = age;
}
Father.prototype.getName = function(){
  console.log(this.name);
}
// NOTE: 這裏注意原型繼承要在,實例化s1變量以前,若是要使用原型鏈上的方法的話
//  子類的原型是父類的一個實例
Son.prototype = new Father;
// NOTE: 修正構造器,這裏注意要將Son的構造器指向賦值爲Son,不然,打印出來的s1是Father對象
Son.prototype.constructor = Son;
Son.prototype.getAge = function(){
  console.log(this.age);
}
var s1 = new Son('李四',22);
console.log(s1); // Son {name:'李四',age:22}
s1.getName(); // 李四
console.log(Son.prototype.constructor); // Son
console.log(s1.constructor); // Son,若是不糾正,則爲Father
s1.getAge(); // 22
//HACK:這裏經過__proto__這個s1實例的屬性找到了Son的prototype,併爲其添加了say的方法
s1.__proto__.say = function(){  
  console.log('hhhhhhhhhhhhhhhhhhhhhhhh');
}
s1.say()  //  打印 hhhhhhhhhhhhhhh
// NOTE: __proto__這個屬性是具體到某個實例化後的對象纔有的屬性,指向他所屬的類的原型
console.log(new Son().__proto__);  //  爲Son對象

我一直使用es6的class來進行面向對象的開發,可是有許多的遺留的原始的es3,es5的js代碼須要理解,因此寫了本文,幫助理清繼承問題

相關文章
相關標籤/搜索