成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

JavaScript七種非常經(jīng)典的創(chuàng)建對(duì)象方式

ARGUS / 2753人閱讀

摘要:創(chuàng)建對(duì)象的方式有很多,通過(guò)構(gòu)造函數(shù)或?qū)ο笞置媪康姆绞揭部梢詣?chuàng)建單個(gè)對(duì)象,顯然這兩種方式會(huì)產(chǎn)生大量的重復(fù)代碼,并不適合量產(chǎn)。四組合使用構(gòu)造函數(shù)模式和原型模式組合使用構(gòu)造函數(shù)模式和原型模式是使用最為廣泛認(rèn)同度最高的一種創(chuàng)建自定義類型的方法。

JavaScript創(chuàng)建對(duì)象的方式有很多,通過(guò)Object構(gòu)造函數(shù)或?qū)ο笞置媪康姆绞揭部梢詣?chuàng)建單個(gè)對(duì)象,顯然這兩種方式會(huì)產(chǎn)生大量的重復(fù)代碼,并不適合量產(chǎn)。接下來(lái)介紹七種非常經(jīng)典的創(chuàng)建對(duì)象的方式,他們也各有優(yōu)缺點(diǎn)。(內(nèi)容主要來(lái)自于《JavaScript高級(jí)程序設(shè)計(jì)》,還參考了一下別人寫(xiě)的文章)

一、工廠模式
function createPerson(name, job) { 
 var o = new Object();
 o.name = name;
 o.job = job;
 o.sayName = function() { 
  console.log(this.name); 
 } 
 return o 
} 
var person1 = createPerson("Mike", "student") 
var person2 = createPerson("X", "engineer") 

可以無(wú)數(shù)次調(diào)用這個(gè)工廠函數(shù),每次都會(huì)返回一個(gè)包含兩個(gè)屬性和一個(gè)方法的對(duì)象。
工廠模式雖然解決了創(chuàng)建多個(gè)相似對(duì)象的問(wèn)題,但是沒(méi)有解決對(duì)象識(shí)別問(wèn)題,即不能知道一個(gè)對(duì)象的類型。

二、構(gòu)造函數(shù)模式
function Person(name, job) { 
 this.name = name;
 this.job = job;
 this.sayName = function() { 
  console.log(this.name);
 } 
} 
var person1 = new Person("Mike", "student") 
var person2 = new Person("X", "engineer") 

沒(méi)有顯示的創(chuàng)建對(duì)象,使用new來(lái)調(diào)用這個(gè)構(gòu)造函數(shù),使用new后會(huì)自動(dòng)執(zhí)行如下操作:
①創(chuàng)建一個(gè)新對(duì)象;
②將構(gòu)造函數(shù)的作用域賦給新對(duì)象(因此this就指向了這個(gè)新對(duì)象);
③執(zhí)行構(gòu)造函數(shù)中的代碼(為這個(gè)新對(duì)象添加屬性);
④返回新對(duì)象。
缺點(diǎn):每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一遍。
創(chuàng)建兩個(gè)完成同樣任務(wù)的的Function實(shí)例的確沒(méi)有必要。況且有this對(duì)象在,根本不用在執(zhí)行代碼前就把函數(shù)綁定到特定的對(duì)象上,可以通過(guò)這樣的形式定義:

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

    this.sayName = sayName;
}

function sayName(){
    alert( this.name );
}

如此一來(lái),就可以將sayName()函數(shù)的定義轉(zhuǎn)移到構(gòu)造函數(shù)外部。而在構(gòu)造函數(shù)內(nèi)部,我們將sayName屬性設(shè)置成全局的sayName函數(shù)。這樣的話,由于sayName包含的是一個(gè)指向函數(shù)的指針,因此person1和person2對(duì)象就可以共享在全局作用域中定義的同一個(gè)sayName()函數(shù)。

這樣做解決了兩個(gè)函數(shù)做同一件事的問(wèn)題,但是新的問(wèn)題又來(lái)了:在全局作用域中定義的函數(shù)實(shí)際上只能被某個(gè)對(duì)象調(diào)用,這讓全局作用域有點(diǎn)名不副實(shí)。而更重要的是:如果對(duì)象需要定義很多方法,那么就需要定義很多個(gè)全局函數(shù),這樣一來(lái),我們自定義的這個(gè)引用類型就毫無(wú)封裝性可言了。

這些問(wèn)題可以通過(guò)使用原型模式來(lái)解決。

三、原型模式
function Person() { 
} 
Person.prototype.name = "Mike" 
Person.prototype.job = "student" 
Person.prototype.sayName = function() { 
 console.log(this.name) 
} 
var person1 = new Person() 

將信息直接添加到原型對(duì)象上。使用原型的好處是可以讓所有的實(shí)例對(duì)象共享它所包含的屬性和方法,不必在構(gòu)造函數(shù)中定義對(duì)象實(shí)例信息,而是可以將這些信息直接添加到原型對(duì)象中。
①理解原型
無(wú)論什么時(shí)候,只要?jiǎng)?chuàng)建了一個(gè)新函數(shù),就會(huì)根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個(gè)prototype屬性。
在默認(rèn)情況下,所有prototype屬性都會(huì)自動(dòng)獲得一個(gè)constructor(構(gòu)造函數(shù))屬性,這個(gè)屬性包含一個(gè)指向prototype屬性所在函數(shù)的指針。
每當(dāng)代碼讀取某個(gè)對(duì)象的某個(gè)屬性時(shí),都會(huì)執(zhí)行一搜索,目標(biāo)是具有給定名字的屬性。搜索首先從對(duì)象實(shí)例本身開(kāi)始。如果在實(shí)例中找到了具有給定名字的屬性,則返回該屬性的值;如果沒(méi)有找到,則繼續(xù)搜索指針指向的原型對(duì)象,在原型對(duì)象中查找具有給定名字的屬性。如果在原型對(duì)象中找到了這個(gè)屬性,則返回該屬性的值。
雖然可以通過(guò)對(duì)象實(shí)例訪問(wèn)保存在原型中的值,但卻不能通過(guò)對(duì)象實(shí)例重寫(xiě)原型中的值。
如果我們?cè)趯?shí)例中添加了一個(gè)屬性,而該屬性與實(shí)例中的一個(gè)屬性同名,那么就會(huì)在實(shí)例中創(chuàng)建該屬性,該屬性將會(huì)屏蔽原型中的那個(gè)屬性。
即使是將屬性設(shè)置為null,也只是在實(shí)例中的屬性值為null。
不過(guò),使用delete操作符可以完全刪除實(shí)例屬性,從而能夠重新訪問(wèn)原型中的屬性。
使用hasOwnProperty() 方法可以檢測(cè)一個(gè)屬性是存在于實(shí)例中,還是存在與原型中。這個(gè)方法只在給定屬性存在于對(duì)象實(shí)例中時(shí),才會(huì)返回true。

②原型與in操作符
in操作符會(huì)在通過(guò)對(duì)象能夠訪問(wèn)給定屬性時(shí)返回true,無(wú)論該屬性是存在于實(shí)例中還是原型中。

③更簡(jiǎn)單的原型語(yǔ)法

function Person(){    
}
Person.prototype = {
    name : "Mike",
    age : 29,
    job : "engineer",    
    syaName : function(){
        alert( this.name );
    }
};

//在上面的代碼中,將Person.prototype設(shè)置為等于一個(gè)以對(duì)象字面量形式創(chuàng)建的新對(duì)象。最終結(jié)果相同,但有一個(gè)例外:constructor屬性不再指向Person。

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

組合使用構(gòu)造函數(shù)模式和原型模式是使用最為廣泛、認(rèn)同度最高的一種創(chuàng)建自定義類型的方法。它可以解決上面那些模式的缺點(diǎn),使用此模式可以讓每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性副本,但同時(shí)又共享著對(duì)方法的引用,這樣的話,即使實(shí)例屬性修改引用類型的值,也不會(huì)影響其他實(shí)例的屬性值了。還支持向構(gòu)造函數(shù)傳遞參數(shù),可謂是集兩種模式的優(yōu)點(diǎn)。

function Person(name) { 
 this.name = name; 
 this.friends = ["Jack", "Merry"]; 
} 
Person.prototype.sayName = function() { 
 console.log(this.name); 
} 
var person1 = new Person(); 
var person2 = new Person(); 
person1.friends.push("Van"); 
console.log(person1.friends) //["Jack", "Merry", "Van"] 
console.log(person2.friends) // ["Jack", "Merry"] 
console.log(person1.friends === person2.friends) //false 
五、動(dòng)態(tài)原型模式

動(dòng)態(tài)原型模式將所有信息都封裝在了構(gòu)造函數(shù)中,初始化的時(shí)候。可以通過(guò)檢測(cè)某個(gè)應(yīng)該存在的方法是否有效,來(lái)決定是否需要初始化原型。

function Person(name, job) { 
  // 屬性 
 this.name = name;
 this.job = job;
 // 方法 
 if(typeof this.sayName !== "function") { 
  Person.prototype.sayName = function() { 
    console.log(this.name) 
  } 
 } 
} 
var person1 = new Person("Mike", "Student") 
person1.sayName() 

只有在sayName方法不存在的時(shí)候,才會(huì)將它添加到原型中。這段代碼只會(huì)初次調(diào)用構(gòu)造函數(shù)的時(shí)候才會(huì)執(zhí)行。此后原型已經(jīng)完成初始化,不需要在做什么修改了,這里對(duì)原型所做的修改,能夠立即在所有實(shí)例中得到反映。
其次,if語(yǔ)句檢查的可以是初始化之后應(yīng)該存在的任何屬性或方法,所以不必用一大堆的if語(yǔ)句檢查每一個(gè)屬性和方法,只要檢查一個(gè)就行。

六、寄生構(gòu)造函數(shù)模式

這種模式的基本思想就是創(chuàng)建一個(gè)函數(shù),該函數(shù)的作用僅僅是封裝創(chuàng)建對(duì)象的代碼,然后再返回新建的對(duì)象

function Person(name, job) { 
  var o = new Object();
 o.name = name;
 o.job = job;
 o.sayName = function() { 
  console.log(this.name) 
 } 
 return o 
} 
var person1 = new Person("Mike", "student") 
person1.sayName() 

這個(gè)模式,除了使用new操作符并把使用的包裝函數(shù)叫做構(gòu)造函數(shù)之外,和工廠模式幾乎一樣。
構(gòu)造函數(shù)如果不返回對(duì)象,默認(rèn)也會(huì)返回一個(gè)新的對(duì)象,通過(guò)在構(gòu)造函數(shù)的末尾添加一個(gè)return語(yǔ)句,可以重寫(xiě)調(diào)用構(gòu)造函數(shù)時(shí)返回的值。

七、穩(wěn)妥構(gòu)造函數(shù)模式

首先明白穩(wěn)妥對(duì)象指的是沒(méi)有公共屬性,而且其方法也不引用this。穩(wěn)妥對(duì)象最適合在一些安全環(huán)境中(這些環(huán)境會(huì)禁止使用this和new),或防止數(shù)據(jù)被其他應(yīng)用程序改動(dòng)時(shí)使用。
穩(wěn)妥構(gòu)造函數(shù)模式和寄生模式類似,有兩點(diǎn)不同:1.是創(chuàng)建對(duì)象的實(shí)例方法不引用this;2.不使用new操作符調(diào)用構(gòu)造函數(shù)

function Person(name, job) { 
 var o = new Object();
 o.name = name;
 o.job = job;
 o.sayName = function() { 
  console.log(name) //注意這里沒(méi)有了"this";
 } 
 return o 
} 
var person1 = Person("Mike", "student") 
person1.sayName();

和寄生構(gòu)造函數(shù)模式一樣,這樣創(chuàng)建出來(lái)的對(duì)象與構(gòu)造函數(shù)之間沒(méi)有什么關(guān)系,instanceof操作符對(duì)他們沒(méi)有意義

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/97052.html

相關(guān)文章

  • 面試寶典

    摘要:有談?wù)劽嬖嚺c面試題對(duì)于前端面試的一些看法。動(dòng)態(tài)規(guī)劃算法的思想及實(shí)現(xiàn)方法幫大家理清動(dòng)態(tài)規(guī)劃的解決思路以及原理方法前端經(jīng)典面試題從輸入到頁(yè)面加載發(fā)生了什么這是一篇開(kāi)發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。極客學(xué)院前端練習(xí)題道練習(xí)題,面試季練練手。 由數(shù)據(jù)綁定和排序引入的幾個(gè) JavaScript 知識(shí)點(diǎn) 在 JavaScript 的數(shù)據(jù)綁定和做簡(jiǎn)單的表格排序中遇到的幾個(gè)知識(shí)點(diǎn) [[JS 基礎(chǔ)...

    neu 評(píng)論0 收藏0
  • JavaScript高級(jí)程序設(shè)計(jì) - CH5

    摘要:在使用字面量表示法的時(shí)候,并不會(huì)調(diào)用對(duì)象的構(gòu)造函數(shù)種常用方法同一樣可通過(guò)和字面量?jī)煞N方法來(lái)創(chuàng)建。直接調(diào)用基本包裝類型的構(gòu)造函數(shù),返回實(shí)例都屬于這個(gè)構(gòu)造函數(shù)是會(huì)根據(jù)參數(shù)返回相應(yīng)的基本包裝類型的實(shí)例。 第五章、引用類型 一共七種引用類型: Object: 可通過(guò)new和字面量?jī)煞N方法來(lái)創(chuàng)建。在使用字面量表示法的時(shí)候,并不會(huì)調(diào)用對(duì)象的構(gòu)造函數(shù) Array: 17種常用方法; 同object...

    bang590 評(píng)論0 收藏0
  • 前端-CSS3&H5

    摘要:高度模型淺識(shí)為的簡(jiǎn)寫(xiě),簡(jiǎn)稱為塊級(jí)格式化上下文,為瀏覽器渲染某一區(qū)域的機(jī)制,中只有和中還增加了和。并非所有的布局都會(huì)在開(kāi)發(fā)中使用,但是其中也會(huì)涉及一些知識(shí)點(diǎn)。然而在不同的純制作各種圖形純制作各種圖形多圖預(yù)警 一勞永逸的搞定 flex 布局 尋根溯源話布局 一切都始于這樣一個(gè)問(wèn)題:怎樣通過(guò) CSS 簡(jiǎn)單而優(yōu)雅的實(shí)現(xiàn)水平、垂直同時(shí)居中。記得剛開(kāi)始學(xué)習(xí) CSS 的時(shí)候,看到 float 屬性不...

    xiaolinbang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

ARGUS

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<