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代碼須要理解,因此寫了本文,幫助理清繼承問題