javascript面向對象編程學習(一)
javascript面向對象編程學習(二) —— 原型鏈繼承javascript
利用call()
或apply()
方法,在子構造函數Child()
中,調用Person.call(this, name)
,加強子構造函數實例;實質等同於複製父實例給子函數。java
function Person(name) {
this.name = name;
this.names = ['大魔王','魔鬼', '惡魔'];
this.getName = function () {
console.log(this.name)
}
}
Person.prototype.say = function (){
console.log('my name is ' + this.name);
}
function Child(name, age){
// 繼承Person
Person.call(this, name);
this.age = age;
}
var child = new Child('小魔王', 22);
var child1 = new Child('大魔王', 25);
console.log(child.names); // ["大魔王", "魔鬼", "惡魔"]
console.log(child1.names); // ["大魔王", "魔鬼", "惡魔"]
child.names.push('小魔王');
console.log(child.names); // ["大魔王", "魔鬼", "惡魔", "小魔王"]
console.log(child1.names); // ["大魔王", "魔鬼", "惡魔"]
console.log(child.name); // 小魔王
console.log(child.age); // 22
複製代碼
call()
或apply()
方法來實現繼承?首先,咱們要了解一下call的定義:調用一個對象的一個方法,以另外一個對象替換當前對象。
也就是說,當執行Person.call(this, name)
的時候,實質就是Person
的this
指向了Child
。
所以,實例child
也有了Person
的屬性和方法了,也就實現了繼承!編程
- 只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法;
Person
的this
指向了Child
, 也就是說,Child
只是複製了Person
的屬性和方法,原型鏈並無和它產生關係;child
實例的__proto__
仍是指向Child
。以下:- 沒法實現構造函數的複用,每一個子類都有父類實例函數的副本,影響性能,代碼會臃腫。
把原型鏈繼承和構造函數繼承的優勢組合起來。使用構造函數繼承實現對實例上的屬性和和方法繼承,使用原型鏈繼承實現對原型上的屬性和方法的繼承。這樣就能使在原型上定義的方法可以實現函數複用,而且沒個實例也有本身的屬性。app
function Person(name) {
this.name = name;
this.names = ['大魔王','魔鬼', '惡魔'];
}
Person.prototype.sayName = function (){
console.log('my name is:' + this.name);
}
function Child(name, age){
// 繼承Person實例屬性
Person.call(this,name);
this.age = age;
}
// 繼承原型的屬性和方法
Child.prototype = new Person();
Child.prototype.constructor = Child; // 由於原型鏈繼承,會把constructor指向改變,因此要從新指回自身
Child.prototype.sayAge = function (){
console.log('my age is:' + this.age);
}
const child = new Child('小魔王', 22);
child.names.push('人');
child.sayName(); // my name is:小魔王
child.sayAge(); // my age is:22
console.log(child.names); // ["大魔王", "魔鬼", "惡魔", "人"]
const child2 = new Child('人', 28);
child2.sayName(); // my name is:人
child2.sayAge(); // my age is:28
console.log(child2.names); // ["大魔王", "魔鬼", "惡魔"]
複製代碼
父類實例的屬性和方法既存在於子類的實例中也存在於原型中。以下圖:函數
想要弄清楚構造函數繼承,要先弄明白
call()
和apply()
方法的定義和使用,要清楚this指向。
組合繼承,當你弄清楚原型鏈繼承和構造函數繼承,而後再把二者結合去思考,就天然而然懂了。
學習的最好的辦法仍是實踐;就譬如我這樣動起手來,畫圖和敲代碼等等,比只看而不去動手,要了解得更加透徹!
你的贊是對我最大的支持,也是我最大的動力!post