最新文章專(zhuān)題視頻專(zhuān)題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專(zhuān)題1關(guān)鍵字專(zhuān)題50關(guān)鍵字專(zhuān)題500關(guān)鍵字專(zhuān)題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專(zhuān)題關(guān)鍵字專(zhuān)題tag2tag3文章專(zhuān)題文章專(zhuān)題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專(zhuān)題3
問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

詳解js創(chuàng)建對(duì)象的幾種方法及繼承

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 21:58:47
文檔

詳解js創(chuàng)建對(duì)象的幾種方法及繼承

詳解js創(chuàng)建對(duì)象的幾種方法及繼承:創(chuàng)建對(duì)象 通過(guò)Object構(gòu)造函數(shù)或?qū)ο笞置媪縿?chuàng)建單個(gè)對(duì)象 這些方式有明顯的缺點(diǎn):使用同一個(gè)接口創(chuàng)建很多對(duì)象,會(huì)產(chǎn)生大量的重復(fù)代碼。為了解決這個(gè)問(wèn)題,出現(xiàn)了工廠模式。 工廠模式 考慮在ES中無(wú)法創(chuàng)建類(lèi)(ES6前),開(kāi)發(fā)人員發(fā)明了一種函數(shù),用函數(shù)來(lái)封裝以特
推薦度:
導(dǎo)讀詳解js創(chuàng)建對(duì)象的幾種方法及繼承:創(chuàng)建對(duì)象 通過(guò)Object構(gòu)造函數(shù)或?qū)ο笞置媪縿?chuàng)建單個(gè)對(duì)象 這些方式有明顯的缺點(diǎn):使用同一個(gè)接口創(chuàng)建很多對(duì)象,會(huì)產(chǎn)生大量的重復(fù)代碼。為了解決這個(gè)問(wèn)題,出現(xiàn)了工廠模式。 工廠模式 考慮在ES中無(wú)法創(chuàng)建類(lèi)(ES6前),開(kāi)發(fā)人員發(fā)明了一種函數(shù),用函數(shù)來(lái)封裝以特

創(chuàng)建對(duì)象

通過(guò)Object構(gòu)造函數(shù)或?qū)ο笞置媪縿?chuàng)建單個(gè)對(duì)象
這些方式有明顯的缺點(diǎn):使用同一個(gè)接口創(chuàng)建很多對(duì)象,會(huì)產(chǎn)生大量的重復(fù)代碼。為了解決這個(gè)問(wèn)題,出現(xiàn)了工廠模式。

工廠模式

考慮在ES中無(wú)法創(chuàng)建類(lèi)(ES6前),開(kāi)發(fā)人員發(fā)明了一種函數(shù),用函數(shù)來(lái)封裝以特定接口創(chuàng)建對(duì)象的細(xì)節(jié)。(實(shí)現(xiàn)起來(lái)是在一個(gè)函數(shù)內(nèi)創(chuàng)建好對(duì)象,然后把對(duì)象返回)。

function createPerson(name,age,job){
 var o=new Object();
 o.name=name;
 o.age=age;
 o.job=job;
 o.sayName=function(){
 alert(this.name);
 };
 return 0;
}

var person1=createPerson("Nicholas",29,"Software Engineer");
var person2=createPerson("Greg",27,"Doctor");

構(gòu)造函數(shù)模式

像Object和Array這樣的原生構(gòu)造函數(shù),在運(yùn)行時(shí)會(huì)自動(dòng)出現(xiàn)在執(zhí)行環(huán)境。此外,也可以創(chuàng)建自定義的構(gòu)造函數(shù),從而定義自定義對(duì)象類(lèi)型的屬性和方法。

function Person(name,age,job){
 this.name=name;
 this.age=age;
 this.job=job;
 this.sayName=function(){
 alert(this.name);
 };
}

var person1=new Person(...);
var person2=new Person(...);

與工廠模式相比,具有以下特點(diǎn):

  1. 沒(méi)有顯式創(chuàng)建對(duì)象;
  2. 直接將屬性和方法賦給了this對(duì)象;
  3. 沒(méi)有return語(yǔ)句;
  4. 要?jiǎng)?chuàng)建新實(shí)例,必須使用new操作符;(否則屬性和方法將會(huì)被添加到window對(duì)象)
  5. 可以使用instanceof操作符檢測(cè)對(duì)象類(lèi)型

構(gòu)造函數(shù)的問(wèn)題:

構(gòu)造函數(shù)內(nèi)部的方法會(huì)被重復(fù)創(chuàng)建,不同實(shí)例內(nèi)的同名函數(shù)是不相等的。可通過(guò)將方法移到構(gòu)造函數(shù)外部解決這一問(wèn)題,但面臨新問(wèn)題:封裝性不好。

原型模式

我們創(chuàng)建的每個(gè)函數(shù)都有一個(gè)prototype屬性,這個(gè)屬性是一個(gè)指針,指向一個(gè)對(duì)象,而這個(gè)對(duì)象的用途是包含可以由特定類(lèi)型的所有實(shí)例共享的屬性和方法。(prototype就是通過(guò)調(diào)用構(gòu)造函數(shù)而創(chuàng)建的那個(gè)對(duì)象實(shí)例的原型對(duì)象)。
使用原型對(duì)象的好處是可以讓所有對(duì)象實(shí)例共享它所包含的屬性和方法。換句話說(shuō),不必在構(gòu)造函數(shù)中定義對(duì)象實(shí)例的信息,而是可以將這些信息直接添加到原型對(duì)象中。

function Person(){
}

Person.prototype.name="Nicholas";
Person.prototype.age=29;
Person.prototype.job="...";
Person.prototype.sayName=function(){
 ...
};

var person1=new Person();
person1.sayName();//"Nicholas"

更常見(jiàn)的做法是用一個(gè)包含所有屬性和方法的對(duì)象字面量來(lái)重寫(xiě)整個(gè)原型對(duì)象,并重設(shè)constructor屬性。

function Person(){
}

Person.prototype={
 name:"...",
 age:29,
 job:"...",
 sayName:function(){
 ...
 }
};

Object.defineProperty(Person.prototype,"constructor",{
 enumerable:false,
 value:Person,
});

原型對(duì)象的問(wèn)題:

他省略了為構(gòu)造函數(shù)傳遞初始化參數(shù)這一環(huán)節(jié),結(jié)果所有實(shí)例在默認(rèn)情況下都將取得相同的屬性值,雖然這會(huì)在一定程度帶來(lái)一定的不便,但不是最大的問(wèn)題,最大的問(wèn)題是由其共享的本性所決定的。
對(duì)于包含基本值的屬性可以通過(guò)在實(shí)例上添加一個(gè)同名屬性隱藏原型中的屬性。然后,對(duì)于包含引用數(shù)據(jù)類(lèi)型的值來(lái)說(shuō),會(huì)導(dǎo)致問(wèn)題。

組合使用構(gòu)造函數(shù)模式和原型模式

這是創(chuàng)建自定義類(lèi)型的最常見(jiàn)的方式。
構(gòu)造函數(shù)模式用于定義實(shí)例屬性,而原型模式用于定義方法和共享的屬性。所以每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本,但同時(shí)共享著對(duì)方法的引用,最大限度的節(jié)省了內(nèi)存。同時(shí)支持向構(gòu)造函數(shù)傳遞參數(shù)。

function Person(name,age,job){
 this.name=name;
 this.age=age;
 this.job=job;
 this.friends=["S","C"];
}

Person.prototype={
 constructor:Person,
 sayName:function(){
 alert(this.name);
 }
};

var person1=new Person(...);

動(dòng)態(tài)原型模式

function Person(name,age,job){
 this.name=name;
 this.age=age;
 this.job=job;

 if(typeof this.sayName!="function"){
 Person.prototype.sayName=function(){
 alert(this.name);
 };
 }
}

這里只有sayName()不存在的情況下,才會(huì)將它添加到原型中,這段代碼只會(huì)在初次調(diào)用構(gòu)造函數(shù)時(shí)才執(zhí)行。這里對(duì)原型所做的修改,能夠立刻在所有實(shí)例中得到反映。

Object.create()

ES5定義了一個(gè)名為Object.create()的方法,它創(chuàng)建一個(gè)新對(duì)象,其中第一個(gè)參數(shù)是這個(gè)對(duì)象的原型,第二個(gè)參數(shù)對(duì)對(duì)象的屬性進(jìn)行進(jìn)一步描述。

Object.create()介紹

Object.create(null) 創(chuàng)建的對(duì)象是一個(gè)空對(duì)象,在該對(duì)象上沒(méi)有繼承 Object.prototype 原型鏈上的屬性或者方法,例如:toString(), hasOwnProperty()等方法

Object.create()方法接受兩個(gè)參數(shù):Object.create(obj,propertiesObject) ;

obj:一個(gè)對(duì)象,應(yīng)該是新創(chuàng)建的對(duì)象的原型。

propertiesObject:可選。該參數(shù)對(duì)象是一組屬性與值,該對(duì)象的屬性名稱(chēng)將是新創(chuàng)建的對(duì)象的屬性名稱(chēng),值是屬性描述符(這些屬性描述符的結(jié)構(gòu)與Object.defineProperties()的第二個(gè)參數(shù)一樣)。注意:該參數(shù)對(duì)象不能是 undefined,另外只有該對(duì)象中自身?yè)碛械目擅杜e的屬性才有效,也就是說(shuō)該對(duì)象的原型鏈上屬性是無(wú)效的。

var o = Object.create(Object.prototype, {
 // foo會(huì)成為所創(chuàng)建對(duì)象的數(shù)據(jù)屬性
 foo: { 
 writable:true,
 configurable:true,
 value: "hello" 
 },
 // bar會(huì)成為所創(chuàng)建對(duì)象的訪問(wèn)器屬性
 bar: {
 configurable: false,
 get: function() { return 10 },
 set: function(value) {
 console.log("Setting `o.bar` to", value);
 }
 }
});
console.log(o);//{foo:'hello'}
var test1 = Object.create(null) ;
console.log(test1);// {} No Properties 
因?yàn)樵赽ar中設(shè)置了configurable 使用set,get方法默認(rèn)都是不起作用,所以bar值無(wú)法賦值或者獲取
這里的o對(duì)象繼承了 Object.prototype Object上的原型方法
我們可以 對(duì)象的 __proto__屬性,來(lái)獲取對(duì)象原型鏈上的方法 如:
console.log(o.__proto__);//{__defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, __lookupSetter__: ƒ, …}
console.log(test1.__proto__);//undefined

通過(guò)打印發(fā)現(xiàn), 將{}點(diǎn)開(kāi),顯示的是 No Properties ,也就是在對(duì)象本身不存在屬性跟方法,原型鏈上也不存在屬性和方法,

new object()

var test1 = {x:1};

var test2 = new Object(test1);

var test3 = Object.create(test1);
console.log(test3);//{} 
//test3等價(jià)于test5
var test4 = function(){
  
}
test4.prototype = test1;
var test5 = new test4();
console.log(test5);
console.log(test5.__proto__ === test3.__proto__);//true
console.log(test2);//{x:1}
var test1 = {};
var test2 = new Object();
var test3 = Object.create(Object.prototype);
var test4 = Object.create(null);//console.log(test4.__proto__)=>undefined 沒(méi)有繼承原型屬性和方法
console.log(test1.__proto__ === test2.__proto__);//true
console.log(test1.__proto__ === test3.__proto__);//true
console.log(test2.__proto__ === test3.__proto__);//true
console.log(test1.__proto__ === test4.__proto__);//false
console.log(test2.__proto__ === test4.__proto__);//false
console.log(test3.__proto__ === test4.__proto__);//false

總結(jié):使用Object.create()是將對(duì)象繼承到__proto__屬性上

var test = Object.create({x:123,y:345});
console.log(test);//{}
console.log(test.x);//123
console.log(test.__proto__.x);//3
console.log(test.__proto__.x === test.x);//true

var test1 = new Object({x:123,y:345});
console.log(test1);//{x:123,y:345}
console.log(test1.x);//123
console.log(test1.__proto__.x);//undefined
console.log(test1.__proto__.x === test1.x);//false

var test2 = {x:123,y:345};
console.log(test2);//{x:123,y:345};
console.log(test2.x);//123
console.log(test2.__proto__.x);//undefined
console.log(test2.__proto__.x === test2.x);//false

繼承

我這里就介紹一種吧,剩下的可以去權(quán)威指南里看去

原型鏈

ECMAScript 中描述了原型鏈的概念,并將原型鏈作為實(shí)現(xiàn)繼承的主要方法。其基本思想是利用原 型讓一個(gè)引用類(lèi)型繼承另一個(gè)引用類(lèi)型的屬性和方法。簡(jiǎn)單回顧一下構(gòu)造函數(shù)、原型和實(shí)例的關(guān)系:每 個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例都包含一個(gè)指向原型 對(duì)象的內(nèi)部指針。那么,假如我們讓原型對(duì)象等于另一個(gè)類(lèi)型的實(shí)例,結(jié)果會(huì)怎么樣呢?顯然,此時(shí)的 原型對(duì)象將包含一個(gè)指向另一個(gè)原型的指針,相應(yīng)地,另一個(gè)原型中也包含著一個(gè)指向另一個(gè)構(gòu)造函數(shù) 的指針。假如另一個(gè)原型又是另一個(gè)類(lèi)型的實(shí)例,那么上述關(guān)系依然成立,如此層層遞進(jìn),就構(gòu)成了實(shí) 例與原型的鏈條。這就是所謂原型鏈的基本概念。

實(shí)現(xiàn)原型鏈有一種基本模式,其代碼大致如下。

function SuperType(){
 this.property = true;
}
SuperType.prototype.getSuperValue = function(){
 return this.property;
};
function SubType(){
 this.subproperty = false;
}
//繼承了 SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
 return this.subproperty;
 };
 var instance = new SubType();
alert(instance.getSuperValue());
//true

以上代碼定義了兩個(gè)類(lèi)型:SuperType 和 SubType。每個(gè)類(lèi)型分別有一個(gè)屬性和一個(gè)方法。它們 的主要區(qū)別是 SubType 繼承了 SuperType,而繼承是通過(guò)創(chuàng)建 SuperType 的實(shí)例,并將該實(shí)例賦給 SubType.prototype 實(shí)現(xiàn)的。實(shí)現(xiàn)的本質(zhì)是重寫(xiě)原型對(duì)象,代之以一個(gè)新類(lèi)型的實(shí)例。換句話說(shuō),原 來(lái)存在于 SuperType 的實(shí)例中的所有屬性和方法,現(xiàn)在也存在于 SubType.prototype 中了。在確立了 繼承關(guān)系之后,我們給 SubType.prototype 添加了一個(gè)方法,這樣就在繼承了 SuperType 的屬性和方 法的基礎(chǔ)上又添加了一個(gè)新方法。這個(gè)例子中的實(shí)例以及構(gòu)造函數(shù)和原型之間的關(guān)系如圖 6-4 所示。

以上所述是小編給大家介紹的js創(chuàng)建對(duì)象的幾種方法及繼承詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

詳解js創(chuàng)建對(duì)象的幾種方法及繼承

詳解js創(chuàng)建對(duì)象的幾種方法及繼承:創(chuàng)建對(duì)象 通過(guò)Object構(gòu)造函數(shù)或?qū)ο笞置媪縿?chuàng)建單個(gè)對(duì)象 這些方式有明顯的缺點(diǎn):使用同一個(gè)接口創(chuàng)建很多對(duì)象,會(huì)產(chǎn)生大量的重復(fù)代碼。為了解決這個(gè)問(wèn)題,出現(xiàn)了工廠模式。 工廠模式 考慮在ES中無(wú)法創(chuàng)建類(lèi)(ES6前),開(kāi)發(fā)人員發(fā)明了一種函數(shù),用函數(shù)來(lái)封裝以特
推薦度:
標(biāo)簽: js 方式 三種
  • 熱門(mén)焦點(diǎn)

最新推薦

猜你喜歡

熱門(mén)推薦

專(zhuān)題
Top