Javascript 6 種繼承

1.原型鏈繼承函數

// 1.原型鏈繼承的兩個問題===》在借用構造函數中能夠解決下下面的兩個問題
//problem: 在建立子類型的實例時,不能向超類型的實例傳遞參數(在這裏就是不能向A()裏傳遞參數)
function A(light) {
this.light1=light;
}
function B(light) {
this.light=light;
}
B.prototype=new A(); //在這裏就會引出屬性被其它實例共享的問題
var c=new B(123);
console.log(c.light);
console.log(c.light1);this

// problem:屬性是引用類型的值時,修改引用類型後,繼承後會被全部實例共享
function C() {
this.color=["red","blue","pink"]
}
function D() {

}
D.prototype=new C();
var instance1=new D();
instance1.color.push("black")
var instance2=new D();
console.log(instance1);
console.log(instance2);spa

2.構造函數繼承prototype

// 借用構造函數的兩個問題
// 1.方法屬性必須定義在借用構造函數以後,不然,從新定義的屬性會被超類型的屬性覆蓋
// 2.函數方法只能定義在構造函數中,沒有函數複用的說法了
function A(name) {
this.city="北京";
this.name=name;
this.countries=["美國","中國","英國"]
}
function B(name,age) {
this.city="上海";
A.call(this,name);
this.age=age;
// this.city="上海";應該寫在這裏
}
var s1=new B("bob",25);
console.log(s1);
s1.countries.push("india");
console.log(s1.city);對象

3.組合繼承繼承

// 組合繼承(構造函數中定義屬性,原型對象中定義方法) 建立的實例會分別擁有本身的屬性 會使用相同的方法。
// 避免了原型鏈繼承與構造函數繼承的缺陷,宗旨,原型鏈繼承共享的屬性和方法,構造函數繼承實例屬性。
function superType(name) {
this.name = name;
this.colors = ["red", "blue"]
}
superType.prototype.sayName = function() {
console.log(this.name) //這裏的方法能夠不用定義在構造函數中了
}ci

function subType(name, age) {
superType.call(this, name);
this.age = age;
}原型鏈

// 繼承方法
subType.prototype = new superType();
subType.prototype.constructor = subType;
subType.prototype.sayAge = function() {
console.log(this.age)
}原型

var instance1 = new subType("jack", 10);
instance1.colors.push("black");
console.log(instance1.colors);
instance1.sayName();
instance1.sayAge();it

var instance2 = new subType("tom", 20);
console.log(instance2.colors);
instance2.sayName();
instance2.sayAge();

 

4.原型式繼承

// 原型式繼承
// 1.problem:包含引用類型的屬性都會被共享
function object(o) {
function F() {}
F.prototype=o;
return new F();

}
var person={
name:"jack",
friends:["a","b","c"]
};
var anotherPerson= Object.create(person);
anotherPerson.name="tom";
anotherPerson.friends.push("d");

var otherPerson=Object.create(person,{
name:{
value:"gg" //2.Object.create的第二個參數會覆蓋原型對象上的同名屬性
}
})
console.log(anotherPerson.name);
console.log(otherPerson.name);

 

5.寄生式組合繼承

// 最完美的繼承,繼生式組合繼承
function superType(name) {
this.name1 = name;
this.colors = ["red", "blue"]
}
superType.prototype.sayName = function() {
console.log(this.name) //3.這裏的方法能夠不用定義在構造函數中了,注意不要在原型對象中定義屬性
}

function subType(name, age) {
superType.call(this, name); //4.這裏的借用構造函數能夠爲每一個實例建立一個屬性副本,構造函數superType只被調用一次,能夠放在構造函數中
this.name = name;
this.age = age;
}

function inheritPrototype(subType,superTyper) {
var prototype=Object.create(superType.prototype); //5.Object.create 就至關於給被繼承的構造函數轉變爲一個對象副本,避免superType被屢次調用
prototype.constructor=subType;
subType.prototype=prototype;
}

inheritPrototype(subType,superType);

var instance1=new subType("張三"); //2.能夠向超類型的屬性傳遞參數
console.log(instance1.name);
var instance2=new subType("張三");
console.log(instance2.name1);

instance1.colors.push("pink");//1.解決了引用類型值會被共享的問題console.log(instance1.colors); console.log(instance2.colors);

相關文章
相關標籤/搜索