js 对象创建及其继承的方法
重新看紅皮書,覺得很多知識多看幾遍確實是能看的更明白些。今天重溫了一下對象創建和繼承,就稍微記下來,鞏固一下。
js是面向對象的編程語言,ECMA-262吧對象定義為:“無序屬性的集合,其屬性可以包含基本值,對象或者函數”。每個對象都是基于一個引用類型創建的,這個引用類型可以是原生類型,也可以是自定義的。
一,講講創建對象的幾個方法
1. var person = new Object();?
2. var person = {};
3. 工廠模式
4. 構造函數模式
5. 原型模式
6. 組合使用構造函數模式和冤案型模式
7. 動態原型模式
8.等等......
這里著重記一下構造模式和原型模式,畢竟之后的模式和繼承方法都是由于這兩個的優缺點借鑒而來。
4.構造函數模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
console.log(this.name);
};
}
var person1 = new Person('niko','19','FE');
?這種方式創建對象,可以將它的實例化標識為一中特定類型。及實例可以通過 instanceof 或者constructor 來檢測對象的類型。缺點是無法完成方法的復用,即每個方法都需要在實例化上重新創建。
5.原型模式
我們自然是希望創建對象時可以共享某些屬性和方法,搞這個原型模式挺拿手的~~~來露個臉。簡單的說,我們創建的每個函數都有一個prototype屬性,這個prototype屬性是一個指針,指向一個對象,這個對象里面放著創建的這個對象實例的原型對象。原型對象,即是包含所有實例都共享的屬性和方法。默認情況下,所有原型對象都自動獲得一個constructor屬性,這個屬性包含一個指向prototype屬性所在函數的指針。繞來繞去估計就暈了,來個圖解釋一下。
通過原型模式創建對象之后,是可以順順利利的完成屬性和方法的共享,但是也是有弊端的如果包含引用類型的值,那么實例化的某一個對象對這個值進行操作,就會修改原型里的值,這樣問題就比較麻煩了。所以組合模式就出現了,及用構造函數來創建屬性,用原型模式來創建共享方法。
7.動態原型模式,就是把所有信息封裝到函數里看著會簡潔好多,也是組合了構造函數和原型模式的優點,在函數內部初始化原型(僅僅在第一次運行時初始化)。
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
if(typeof this.sayName!= "function"){
Person.prototype.sayName = function(){
console.log(this.name);
};
}
}
var person1 = new Person('niko','19','FE');
跟組合模式不同的是,初始化原型在函數內部,并且如果有多個共享函數時,只判斷一個就好~~看著簡潔那么一小丟~~對象創建就寫到這,接下來寫一下繼承啦啦啦啦~
二,常見的繼承方式
1.原型鏈
2.借用構造函數
3.組合繼承
4.組合寄生式繼承
5.原型式,寄生式..
挑幾個重要的講吧,重要的就是掌握原型鏈的原理,以及構造函數繼承方式,組合是采取了這兩個優缺點進行優化,組合寄生則是針對組合繼承進行的優化。原型、寄生式是對一個相對的對象來創建另一個,沒怎么碰到就不講了。
1.原型鏈
原型鏈的主要思想就是讓一個引用類型繼承另一個引用類型的實例。原型對象將包含一個指向另一個原型的指針,另一個原型中也包含指向另一個構造函數的指針。層層遞進之后,形成原型鏈。
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
};
function Subtype(){
this.subproperty = false;
}
Subtype.prototype.getSubValue = function(){
return this.subproperty;
}
Subtype.prototype.getSubValue = function(){
return this.subproperty;
};
var instance = new Subtype();
啊,寫到一半突然要閉館了閉館了閉館了=.=淚奔一下 ,中間詳細就不解釋了,看懂這個圖就沒啥大問題了~原型鏈的問題就是,共享引用類型值的時候,修改一個實例就會修改原型。
2.借用構造函數
這個方法就是在子類構造函數中調用超類的構造函數。
function SuperType(name){
this.name = name;
}
function SubType(){
SuperType.call(this,'niko'); //在this的作用域中調用SuperType()
}
var instance = new SubType();
這種方式不像原型繼承,相當于在子類的作用域中吧超類的屬性完完全全復制了一份。因為不是引用的指針,所以,即使是引用類型的屬性值,每個實例都會復制一份屬性值,所以不會有什么問題噠~~~而且借用構造函數模式可以在子類中傳參。
3.組合繼承就是兼顧了原型模式和借用構造函數模式的優缺點。既可以共享方法,也可以讓不同的實例分別有自己的屬性。
??
function SuperType(name){
this.name = name;
this.colors = ['red','blue','orange'];
}
SuperType.prototype.sayName = function(){
console.log(this.name);
}
function SubType(name,age){
//繼承屬性
SuperType.call(this,name); //第二次調用SuperType()
this.age = age;
}
SubType.prototype.sayAge = function(){
console.log(this.age);
}
//繼承方法
SubType.prototype = new SuprType(); //第一次調用SuperType();
var instance = new Subtype('niko',34);
如圖所示,第一次調超類的時候,SubType.prototype得到兩個屬性:name,colors。調用Subtype構造函數時,第二次調用超類,在新對象上創建實例屬性:name,colors。這兩個實例屬性屏蔽了原型中的屬性。
這種方法可以達到既可以共享方法,也可以有自己的實例屬性,但是調用兩次超類的構造函數。
4.寄生組合式繼承
為了解決組合式的缺點,寄生組合式這個超級大Boss上場了。
大體思路還是借用構造函數來繼承屬性,用原型鏈的混成方法機場方法。與組合 方式不同的是,沒有在子類中調用超類,而是取得了一個超類的副本。
function inhertiPrototype(subType,superType){
var prototype = object(superType.prototype); //創建對象
prototype.constructor = subType; //增強對象
subType.prototype = prototype; //指定對象
}
?
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/echo-yaonie/p/4639396.html
總結
以上是生活随笔為你收集整理的js 对象创建及其继承的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++实现glut绘制点、直线、多边形、
- 下一篇: 【第一行代码笔记】(一)