es5与es6继承思考

软件设计 2017-03-31

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代码需要理解,所以写了本文,帮助理清继承问题

相关推荐