1.call的借用繼承
function parent1() {
this.name = "parent1"
}
function child1() {
parent1.call(this)
this.type = 'child1'
}
parent1.prototype.say = function () {
console.log('hi parent1')
}
var s1 = new child1();
console.log(s1); //{name: "parent1", type: "child1"}
console.log(s1.say()); //Uncaught TypeError: s1.say is not a function
上述代碼中,關於在parent1中的屬性,可以給子級繼承,但是在parent1原型鏈上的方法,無法給子級繼承。
2. 原型鏈繼承
function parent2() {
this.name = 'parent2';
this.arr = [1,2,3];
}
function child2 () {
this.type = 'child2';
}
parent2.prototype.say = function () {
console.log('hi parent2');
}
child2.prototype = new parent2();
var a1 = new child2();
var a2 = new child2();
a1.say() // hi parent2
a2.say() // hi parent2
a1.arr.push(4);
console.log(a1.arr, a2.arr); // [1, 2, 3, 4], [1, 2, 3, 4]
上述代碼中,child2構造函數的prototype屬性指向父級實例,子級實例中可以使用say方法,但是缺點是child2原型上的屬性值,所有實例皆可訪問。修改了一個實例,其他的都發生改變
3.組合繼承
function parent3() {
this.name = 'parent3';
this.arr = [1,2,3];
}
function child3() {
parent3.call(this);
this.type = 'child3';
}
parent3.prototype.say = function () {
console.log('hi parent3');
}
child3.prototype = new parent3();
var a3 = new child3();
var a4 = new child3();
a3.say(); a4.say() // hi parent3
a3.arr.push(4);
console.log(a3, a4); //[1, 2, 3, 4], [1, 2, 3]
上述代碼中,使用call借用繼承屬性值,使用原型鏈繼承其中方法
4. 組合繼承的優化1
在3中的代碼中,因爲屬性已經被call繼承,所以原型鏈中不需要再次繼承, 所以將
child3.prototype = parent3.prototype // 其他部分不變
5.組合繼承的優化2
在優化之前,先介紹一個創建對象的方法,Object.create可創建一個新對象,使用現有對象來爲新對象提供__proto__
var p1 = {"name": ''};
var obj = Object.create(p1);
console.log(obj);
開始優化:
當對3和4中代碼打印時
console.log(a3 instanceof parent3, a3 instanceof child3);
console.log(a3.constructor);
它們的構造器都是parent3,父級構造,我們知道a3實例是由child3構造出的。所以要改變constructor的指向問題
function parent5() {
this.name = 'parent5';
this.arr = [1,2,3];
}
function child5() {
parent5.call(this);
this.type = 'child5';
}
parent5.prototype.say = function () {
console.log('hi parent5');
}
child5.prototype = Object.create(parent5.prototype); //原型指向一個空對象實例,空對象的__proto__指向parent5.prototype
child5.prototype.constructor = child5;
var s3 = new child5();
var s4 = new child5();
s3.say(); s4.say() // hi parent5
s3.arr.push(4);
console.log(s3, s4); //[1, 2, 3, 4], [1, 2, 3]