国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

《javascript高級程序設計》第六章 讀書筆記 之 javascript對象的幾種創建方式

xiaotianyi / 1045人閱讀

摘要:三種使用構造函數創建對象的方法和的作用都是在某個特殊對象的作用域中調用函數。這種方式還支持向構造函數傳遞參數。叫法上把函數叫做構造函數,其他無區別適用情境可以在特殊的情況下用來為對象創建構造函數。

一、工廠模式

工廠模式:使用字面量和object構造函數會有很多重復代碼,在此基礎上改進

解決了多個相似對象的問題,但沒有解決對象識別的問題(即怎樣知道一個對象的類型)

二、構造函數模式


與工廠模式創建對象的不同之處:沒有顯示創建對象,直接將屬性和方法賦給this對象,沒有return語句。默認return的是this對象。
構造函數本身也是函數,只是可以用來創建對象,所以借鑒自其他面向對象語言,構造函數始終應該以一個大寫字母開頭,非構造函數用一個小寫字母開頭,用于區別構造函數與其他普通函數。
new操作符創建對象實例,經歷4個步驟:
1、創建一個新對象
2、講構造函數的作用域賦給新對象(所以此時this指向這個新對象)
3、執行構造函數中的代碼(為這個新對象添加屬性)
4、返回新對象
上面的實例a又一個constructor(構造函數)屬性指向Person。

相比較工廠模式的有點:有constructor屬相,可以標志為一種特性的類型。
但實際用來檢測對象類型,instanceod更方便些,所以instanceof比較的是constructor屬性。
三種使用構造函數創建對象的方法:

call和apply的作用都是在某個特殊對象的作用域中調用Person()函數。那么上例中,otherPerson的作用域中調用Person函數,this指向otherPerson對象,執行構造函數中的內容,this.name指otherPerson.name=‘shirley’
構造函數模式的缺點:每創建一個實例都要執行一遍構造函數的語句,每個實例有不同的屬性值很正常,也有許多內容一模一樣的方法,這些方法重復創建(實際是new function實例,所以person1.sayname!=otherPerson.sayname。因為sayName方法是不同實例,引用地址不同)則顯得冗余。
很明顯,如果實例引用同一個sayName實例(同一個方法)就能夠解決上述問題。

Person的sayName引用的都是同一個sayName函數,即全局變量中的sayName函數。

三、原型模式

利用每個函數都有的一個prototype(原型)屬性。這個屬性是一個指針,指向一個對象,這個對象的用途是包含可以由特定類型的所有實例共享的屬性和方法。(解決了構造函數模式的缺點)
prototype就是通過調用構造函數而創建的那個對象實例的原型對象。(就是所創建的對象的原型,例如:var person1=new Person(’linda‘,15)person1的原型為Person。otherPerson=new Object() otherPerson的原型為Object)
例子:

判斷一個對象的prototype是否指向某對象

訪問一個對象的prototype屬性

Firef、Safari、Chrome中支持一個屬性__proto__可以訪問到prototype
注意: JavaScript 中任意對象都有一個內置屬性 [[Prototype]] ,在ES5之前沒有標準的方法訪問這個內置屬性,但是大多數瀏覽器都支持通過__proto__來訪問。以下統一使用__proto__來訪問 [[Prototype]],在實際開發中是不能這樣訪問的。(摘自:https://segmentfault.com/a/11...)
ES5中增加了一個新方法,Object.getPrototyOf()

“原型最初只包含constructor屬性”即,對象的constructor保存在原型屬性中。
對象實例不能改變原型中的值,所以當我們試圖改變原型中的值時,會在實例中新添加一個相同名稱的屬性。當我們訪問這個屬性時,就會優先返回實例中的屬性,這就是覆蓋了原型的屬性。
那么我們怎么確定一個屬性是來自對象實例還是來自對象的原型,使用Object對象的hasOwnProperty()方法可以檢測屬性是否存在于對象實例中,若存在,則訪問的屬性必定是來自對象實例,因為當訪問一個屬性時,先搜索對象屬性若不存在才會去搜索對象的原型屬性的。

delete可以刪除實例的屬性,但不能刪除對象原型中的屬性。
對象、構造函數(constructor)和原型(Prototype)的聯系:
如下圖

person1和person2實例中的prototype屬性中保存的是Person的原型,原型里有constructor屬性又指向Person。所以對象和constructor之間是通過原型聯系起來的。

確定屬性是原型中的屬性:
in操作符只要通過對象能夠訪問到屬性就返回true,不管是實例的屬性還是原型中的屬性,所以通過in操作符返回true兒hasOwnProperty()返回false就可以確定屬性是原型中的屬性。

用字面量法定義Person的prototype屬性:

會造成constructor屬性不再指向Person
我們知道,沒創建一個函數,就會同時創建它的prototype對象,這個對象也會自動獲得constructor屬性。使用字面量定義prototype會重寫這個對象,因此constructor會變成新的對象的constructor屬性(指向object構造函數)。
打印person2顯示:

紅框內沒有constructor屬性。我們知道person2.constructor會尋找person2對象中的constructor對象中的constructor對象,person2實例對象中沒有,尋找原型中(紅框)也沒有,繼續尋找prototype的原型對象即object對象,所以,person2.constructor===Object true;

原型模式創建對象是在函數構造模式的基礎上解決共有方法和屬性的,那么函數構造模式是為了解決字面量法的無法判斷是哪個對象的問題而出現,怎么判斷?通過對象的constructor屬性判斷,現在原型的constructor都指向對象,就把這個優勢抹去了,所以出現下面這樣的方法來保存這個特性。

這樣做與原來的差別是:constructor屬性的[[Enumberable]]特性被設置為true,原來是false(不可枚舉)。所以如果使用兼容EXMAScript5的JavaScript引擎,可以使用Object.defineProperty()

原型具有動態性。
構造函數的原型改變會立即反映到所有實例中,但如果是重新寫一個原型對象則不會了



原因:person1的構造函數會自動指向一個原型對象,而保存的是這個原型對象的指針,新建一個prototype對象后,在堆內存中開辟了一個新的對象空間,在person2中保存的是這個新對象的引用指針,所以兩者不同。
原型模式很少會多帶帶使用,因為所有屬性都是共享的,但實力一般都是要有屬于自己的全部屬性的。原型模式無法做到,所以這是原型模式的缺點。

四、組合使用構造函數和原型模式

創建自定義類型的最常見方式,構造函數模式用于定義實例屬性,原型模式用于定義方法和共享的屬性。

結果每個人實例都有自己的一份實例屬性的副本,同時又共享著對方法的引用,最大限度地節省了內存。這種方式還支持向構造函數傳遞參數。(既有構造函數模式的優點又有原型模式的優點)

五、動態原型模式

在構造函數中判斷是否存在sayName函數,如果不存在添加到原型中,下圖創建了兩次對象,調用兩次構造函數,但if的判斷只執行一次,在第一次執行。

六、寄生構造函數模式

與工廠模式在寫法上紅框圈出不同之外一模一樣。叫法上把Person函數叫做構造函數,其他無區別

適用情境:
可以在特殊的情況下用來為對象創建構造函數。假如我們想創建一個具有額外方法的特殊數組。

七、穩妥構造函數模式

穩妥對象:沒有公共屬性,而且其方法也不引用this的對象。
穩妥對象最適合在一些安全的環境中(這些環境中會禁止是使用this和new),或者在防止數據被其他應用程序(如Mashup程序)改動時使用。
穩妥構造函數與寄生構造函數類似的模式。不同點:1、新創建對象的實例方法不引用this,2、不適用new操作符調用構造函數。


所以,使用穩妥構造函數模式創建的對象與構造函數之間沒有關系,無法用instanceod判斷所屬類型。
之所以穩妥,是因為除了sayName方法外部無法對傳入構造函數中的原始數據進行訪問。即使可以給這個對象添加方法或數據成員。
使用環境:某些安全執行環境下使用(ADsafe和Caja)

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100735.html

相關文章

  • javascript高級程序設計六章 讀書筆記 javascript繼承的6種方法

    摘要:繼承的是超類型中構造函數中的屬性,如上繼承了屬性,但沒有繼承原型中的方法。上述造成的結果是子類型實例中有兩組超類型的構造函數中定義的屬性,一組在子類型的實例中,一組在子類型實例的原型中。 ECMAScript只支持實現繼承,主要依靠原型鏈來實現。與實現繼承對應的是接口繼承,由于script中函數沒有簽名,所以無法實現接口繼承。 一、原型鏈 基本思想:利用原型讓一個引用類型繼承另一個引用...

    孫吉亮 評論0 收藏0
  • 高程讀書筆記 六章 面向對象程序設計

    摘要:創建一個新對象將構造函數的作用域賦給新對象因此就指向了這個新對象執行構造函數中的代碼為這個新對象添加屬性返回新對象。 本章內容 理解對象屬性 理解并創建對象 理解繼承 ECMA-262把對象定義為:無序屬性的集合,其屬性可以包含基本值、對象或者函數 理解對象 創建對象 創建自定義對象的最簡單方式就是創建一個Object的實例,再為它添加屬性和方法。 var person = new...

    468122151 評論0 收藏0
  • JS高程讀書筆記--六章原型繼承

    摘要:高程讀書筆記第六章理解對象創建自定義對象的方式有創建一個實例,然后為它添加屬性和方法。創建了自定義的構造函數之后,其原型對象默認只會取得屬性至于其他方法都是從繼承而來的。 JS高程讀書筆記--第六章 理解對象 創建自定義對象的方式有創建一個Object實例,然后為它添加屬性和方法。還可用創建對象字面量的方式 屬性類型 ECMAScript在定義只有內部采用的特性時,描述了屬性的各種特征...

    EasonTyler 評論0 收藏0
  • 《Python基礎教程》六章--讀書筆記

    摘要:第六章抽象本章會介紹如何將語句組織成函數。關鍵字參數和默認值目前為止,我們使用的參數都是位置參數,因為它們的位置很重要,事實上比它們的名字更重要。參數前的星號將所有值放置在同一個元祖中。函數內的變量被稱為局部變量。 第六章:抽象 本章會介紹如何將語句組織成函數。還會詳細介紹參數(parameter)和作用域(scope)的概念,以及遞歸的概念及其在程序中的用途。 懶惰即美德 斐波那契數...

    AnthonyHan 評論0 收藏0
  • 讀書筆記(06) - 語法基礎 - JavaScript高級程序設計

    摘要:寫在開頭本篇是小紅書筆記的第六篇,也許你會奇怪第六篇筆記才寫語法基礎,筆者是不是穿越了??梢撇焦P者的文章中替換方式參考文檔高級程序設計作者以樂之名本文原創,有不當的地方歡迎指出。 showImg(https://segmentfault.com/img/bVblGMc?w=600&h=400); 寫在開頭 本篇是小紅書筆記的第六篇,也許你會奇怪第六篇筆記才寫語法基礎,筆者是不是穿越了。...

    iOS122 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<