淺談js中Object.create()與new的具體實(shí)現(xiàn)與區(qū)別
Object.create與new區(qū)別
function A() {
this.name = 'abc';
}
A.prototype.a = 'a';
A.prototype.showName = function () {
return this.name;
}
var a1 = new A();
var a2 = Object.create(A.prototype);


從這個(gè)例子可以看出,a2只繼承了A原型的屬性和方法,
a1 是構(gòu)造函數(shù) A 的實(shí)例,繼承了構(gòu)造函數(shù) A 的屬性 name及其原型屬性和方法。
所以O(shè)bject.create()與new的區(qū)別在于Object.create只繼承原型屬性和方法,繼承不了構(gòu)造函數(shù)的屬性和方法。而通過new操作符創(chuàng)建的實(shí)例,既可以繼承原型的屬性和方法,又可以繼承構(gòu)造函數(shù)的屬性和方法。
Object.create()原理
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
new原理
- 創(chuàng)建一個(gè)空對(duì)象obj;
- 將該空對(duì)象的原型設(shè)置為構(gòu)造函數(shù)的原型,即obj.proto = func.prototype;
- 以該對(duì)象為上下文執(zhí)行構(gòu)造函數(shù),即func.call(obj);
- 返回該對(duì)象,即return obj。
var newFunc = function ( func ){
var obj = Object.creat(func.prototype);
var ret = func.call(obj);
if(typeof ret === 'object') {
return ret;
}
else {
return obj;
}
}
從兩者的具體實(shí)現(xiàn)可以看出:Object.create沒有執(zhí)行步驟三,所以繼承不了構(gòu)造函數(shù)的屬性和方法。
繼承
a1.__proto__ == a2.__proto__; // true a1.__proto__ == A.prototype; // true a2.__proto__ == A.prototype; // true a1.__proto__.__proto__ == Object.prototype; // true a1.__proto__.__proto__.__proto__ == null; // true
比較組合繼承與寄生組合繼承
組合繼承
在子類構(gòu)造函數(shù)中調(diào)用父類構(gòu)造函數(shù),并把父類實(shí)例化對(duì)象賦給子類原型。
function Parent(name, age) {
this.name = name;
this.age = age;
}
Parent.prototype.showName = function () {
return this.name;
}
function Child(name, age) {
Parent.call(this, name, age); // 這里調(diào)用一次父類構(gòu)造函數(shù)
}
Child.prototype = new Parent(); // 這里也會(huì)調(diào)用父類構(gòu)造函數(shù)
Child.prototype.constructor = Child;
這種方式在構(gòu)造函數(shù)繼承時(shí)執(zhí)行了一遍父類構(gòu)造函數(shù),又在實(shí)現(xiàn)子類原型繼承時(shí)調(diào)用了一遍父類的構(gòu)造函數(shù)。因此父類構(gòu)造函數(shù)調(diào)用了兩遍,所以這不是最優(yōu)化的繼承方式。
寄生組合繼承
function Parent(name, age) {
this.name = name;
this.age = age;
}
Parent.prototype.showName = function () {
return this.name;
}
function Child(name, age) {
Parent.call(this, name, age); // 這里調(diào)用一次父類構(gòu)造函數(shù)
}
Child.prototype = Object.create(Parent.prototype); // 這里避免了調(diào)用父類構(gòu)造函數(shù)
Child.prototype.constructor = Child;
到此這篇關(guān)于淺談js中Object.create()與new的具體實(shí)現(xiàn)與區(qū)別的文章就介紹到這了,更多相關(guān)Object.create()與new區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
原生js實(shí)現(xiàn)簡(jiǎn)單滑動(dòng)解鎖功能?js實(shí)現(xiàn)滑動(dòng)拼圖解鎖
這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)簡(jiǎn)單滑動(dòng)解鎖功能,js實(shí)現(xiàn)滑動(dòng)拼圖解鎖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
js動(dòng)態(tài)添加帶圓圈序號(hào)列表的實(shí)例代碼
這篇文章主要介紹了js動(dòng)態(tài)添加帶圓圈序號(hào)列表的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
微信小程序?qū)崿F(xiàn)自定義picker選擇器彈窗內(nèi)容
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)自定義picker選擇器彈窗內(nèi)容,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
bootstrap選項(xiàng)卡擴(kuò)展功能詳解
這篇文章主要為大家詳細(xì)介紹了bootstrap選項(xiàng)卡擴(kuò)展功能,增加關(guān)閉,超出一行顯示下拉,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
JS基礎(chǔ)之undefined與null的區(qū)別分析
在JavaScript開發(fā)中,被人問到:null與undefined到底有啥區(qū)別?一時(shí)間不好回答,特別是undefined,因?yàn)檫@涉及到undefined的實(shí)現(xiàn)原理。2011-08-08

