软件设计 2017-03-31
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
javascript给对象提供了一个__proto__的隐藏属性,某个对象的__proto__属性默认会指向它的构造器的原型对象. 这个是被实例化后的某个具体的对象才有的属性,是个指向。
这里prototype是个对象 在es5中可以借助ClassMy.prototype.fn = function(){}来对类进行添加可以被所有子类继承的方法。 我在es6中基本没用到这个属性。
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对象