摘要:創(chuàng)建對(duì)象使用或者對(duì)象字面量都可以創(chuàng)建對(duì)象,但是這樣創(chuàng)建的對(duì)象過(guò)于簡(jiǎn)單,不易于對(duì)象的屬性與方法的擴(kuò)展與繼承。下面講的對(duì)象可以與中的做類比。通過(guò)調(diào)用構(gòu)造函數(shù)創(chuàng)建的那個(gè)對(duì)象實(shí)例的原型對(duì)象。
創(chuàng)建對(duì)象
使用new Object()或者對(duì)象字面量都可以創(chuàng)建對(duì)象,但是這樣創(chuàng)建的對(duì)象過(guò)于簡(jiǎn)單,不易于對(duì)象的屬性與方法的擴(kuò)展與繼承。
下面講的對(duì)象可以與JavaEE中的bean做類比。
對(duì),首先可能想到的是使用設(shè)計(jì)模式中的工廠模式
function createPizza(type) { var o = new Object(); o.type = type; o.bake = function() { alert("Start~"); alert(this.type); alert("End~"); }; return o; } var cheesePizza = createPizza("cheese"); var veggiePizza = createPizza("veggie"); cheesePizza.bake();優(yōu)點(diǎn)
工廠模式解決了創(chuàng)建多個(gè)類似對(duì)象的問(wèn)題
缺點(diǎn)對(duì)象無(wú)法識(shí)別,即創(chuàng)建出來(lái)的對(duì)象無(wú)法通過(guò)instanceof等分析出屬于哪種類型
構(gòu)造函數(shù)模式用構(gòu)造函數(shù)可用來(lái)創(chuàng)建特定類型的對(duì)象
// 構(gòu)造函數(shù)首字母遵循OO語(yǔ)言慣例進(jìn)行大寫(xiě) function Pizza(type) { this.type = type; this.bake = function() { alert("Start~"); alert(this.type); alert("End~"); }; } var cheesePizza = new Pizza("cheese"); var veggiePizza = new Pizza("veggie"); cheesePizza.bake();
與工廠模式相比:
沒(méi)有在方法中顯示創(chuàng)造對(duì)象(o);
直接將屬性與方法賦值給this;
沒(méi)有return語(yǔ)句
在用new的時(shí)候,會(huì)經(jīng)歷一下4步:
創(chuàng)建一個(gè)新對(duì)象
將構(gòu)造函數(shù)的作用域賦值給新對(duì)象(此時(shí)this指向新對(duì)象)
執(zhí)行構(gòu)造函數(shù)代碼(為對(duì)象添加屬性)
返回新對(duì)象
如果不使用new,將構(gòu)造函數(shù)當(dāng)做函數(shù)使用,則this指向Global對(duì)象(在瀏覽器中為window對(duì)象),當(dāng)然,可以使用call方法來(lái)指定作用域,例如
var o = new Object(); Pizza.call(o, "salty"); o.bake();
使用構(gòu)造函數(shù)方法,每個(gè)實(shí)例對(duì)象都有一個(gè)constructor構(gòu)造函數(shù)屬性,該屬性指向Pizza(使用對(duì)象字面量、工廠模式方法創(chuàng)建的對(duì)象該屬性指向Object)
cheesePizza.constructor == Pizza
檢查某個(gè)對(duì)象屬于哪種類型,一般使用instanceof,cheesePizza同時(shí)屬于Pizza與Object(之所以屬于Object,是因?yàn)樗袑?duì)象均繼承于Object)
cheesePizza instanceof Pizza; cheesePizza instanceof Object;優(yōu)點(diǎn)
與工廠模式相比,構(gòu)造函數(shù)模式能夠識(shí)別出對(duì)象類型
與下面的原型模式相比,能夠?qū)崿F(xiàn)對(duì)象屬性的互相獨(dú)立,在引用類型屬性上很有用
每個(gè)實(shí)例對(duì)象的方法都是獨(dú)立的,導(dǎo)致方法不能夠共享
原型模式每個(gè)函數(shù)(不是實(shí)例對(duì)象)都有一個(gè)prototype屬性,該屬性是一個(gè)指針,指向一個(gè)對(duì)象,對(duì)象的用途是包含所有實(shí)例共享的屬性和方法。prototype通過(guò)調(diào)用構(gòu)造函數(shù)創(chuàng)建的那個(gè)對(duì)象實(shí)例的原型對(duì)象。使用原型對(duì)象的好處是可以讓所有實(shí)例對(duì)象共享屬性與方法。
function Pizza() { } Pizza.prototype.type = "original" Pizza.prototype.bake = function() { alert("Start~"); alert(this.type); alert("End~"); }; var cheesePizza = new Pizza(); cheesePizza.type = "cheese"; var veggiePizza = new Pizza(); veggiePizza.type = "veggie"; cheesePizza.bake(); veggiePizza.bake();
各個(gè)對(duì)象共享屬性與方法,同時(shí)每個(gè)對(duì)象都可以建立自己的屬性,并屏蔽掉原型對(duì)象的同名屬性,因?yàn)楣蚕韺傩耘c方法,所以以下等式成立
cheesePizza.bake == veggiePizza.bake對(duì)象字面量重寫(xiě)原型對(duì)象
也可以通過(guò)對(duì)象字面量來(lái)重寫(xiě)整個(gè)原型對(duì)象:
Pizza.prototype = { type: "original", bake: function() { alert("Start~"); alert(this.type); alert("End~"); } }
這樣完全重寫(xiě),原型對(duì)象上的constructor屬性不再指向Pizza函數(shù)(全新的constructor指向Object),不過(guò)不影響通過(guò)instanceof來(lái)識(shí)別對(duì)象類型。如果constructor特別重要的話,可以顯式將它置為適當(dāng)?shù)闹担?/p>
Pizza.prototype = { constructor: Pizza, type: "original", bake: function() { alert("Start~"); alert(this.type); alert("End~"); } }
不過(guò)這種方式會(huì)將constructor的屬性特征變?yōu)榭擅杜e,而默認(rèn)情況下它是不可枚舉的,如果想不可枚舉,可以使用Object.defineProperty()方法。
原型的動(dòng)態(tài)性對(duì)原型對(duì)象的修改會(huì)體現(xiàn)在實(shí)例對(duì)象上,即使實(shí)例對(duì)象先被創(chuàng)建。但是通過(guò)對(duì)象字面量重寫(xiě)的原型對(duì)象則沒(méi)有該動(dòng)態(tài)性
優(yōu)點(diǎn)定義在原型對(duì)象上的屬性,能夠保證在各實(shí)例對(duì)象上的共享
缺點(diǎn)對(duì)于引用類型的屬性,各實(shí)例的共享會(huì)導(dǎo)致額外的問(wèn)題。
組合使用構(gòu)造函數(shù)模式與原型模式整合構(gòu)造函數(shù)模式與原型模式,構(gòu)造函數(shù)模式用于定義實(shí)例屬性,原型模式用于定義方法和共享屬性。
動(dòng)態(tài)原型模式 寄生構(gòu)造函數(shù)模式 穩(wěn)妥構(gòu)造函數(shù)模式 各創(chuàng)建模式在Chrome瀏覽器中的表現(xiàn)可以通過(guò)Chrome瀏覽器觀察使用工廠模式創(chuàng)建的cheesePizza對(duì)象屬性為:
cheesePizza {type: "cheese", bake: ?} bake: ? () type: "cheese" __proto__: constructor: ? Object() hasOwnProperty: ? hasOwnProperty() isPrototypeOf: ? isPrototypeOf() propertyIsEnumerable: ? propertyIsEnumerable() toLocaleString: ? toLocaleString() toString: ? toString() valueOf: ? valueOf() __defineGetter__: ? __defineGetter__() __defineSetter__: ? __defineSetter__() __lookupGetter__: ? __lookupGetter__() __lookupSetter__: ? __lookupSetter__() get __proto__: ? __proto__() set __proto__: ? __proto__()
使用構(gòu)造函數(shù)模式創(chuàng)建cheesePizza對(duì)象屬性為:
cheesePizza Pizza {type: "cheese", bake: ?} bake: ? () type: "cheese" __proto__: constructor: ? Pizza(type) __proto__: constructor: ? Object() hasOwnProperty: ? hasOwnProperty() isPrototypeOf: ? isPrototypeOf() propertyIsEnumerable: ? propertyIsEnumerable() toLocaleString: ? toLocaleString() toString: ? toString() valueOf: ? valueOf() __defineGetter__: ? __defineGetter__() __defineSetter__: ? __defineSetter__() __lookupGetter__: ? __lookupGetter__() __lookupSetter__: ? __lookupSetter__() get __proto__: ? __proto__() set __proto__: ? __proto__()
使用原型模式創(chuàng)建cheesePizza對(duì)象屬性為:
cheesePizza Pizza {type: "cheese"} type: "cheese" __proto__: bake: ? () type: "original" constructor: ? Pizza() __proto__: constructor: ? Object() hasOwnProperty: ? hasOwnProperty() isPrototypeOf: ? isPrototypeOf() propertyIsEnumerable: ? propertyIsEnumerable() toLocaleString: ? toLocaleString() toString: ? toString() valueOf: ? valueOf() __defineGetter__: ? __defineGetter__() __defineSetter__: ? __defineSetter__() __lookupGetter__: ? __lookupGetter__() __lookupSetter__: ? __lookupSetter__() get __proto__: ? __proto__() set __proto__: ? __proto__()參考文章
ESLint 需要約束 for-in (guard-for-in)
個(gè)人不定期更新主頁(yè)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/100145.html
摘要:執(zhí)行上下文作用域鏈和內(nèi)部機(jī)制一執(zhí)行上下文執(zhí)行上下文是代碼的執(zhí)行環(huán)境,它包括的值變量對(duì)象和函數(shù)。創(chuàng)建作用域鏈一旦可變對(duì)象創(chuàng)建完,引擎就開(kāi)始初始化作用域鏈。 執(zhí)行上下文、作用域鏈和JS內(nèi)部機(jī)制(Execution context, Scope chain and JavaScript internals) 一、執(zhí)行上下文 執(zhí)行上下文(Execution context EC)是js代碼的執(zhí)...
摘要:當(dāng)這步完成,這個(gè)對(duì)象就與構(gòu)造函數(shù)再無(wú)聯(lián)系,這個(gè)時(shí)候即使構(gòu)造函數(shù)再加任何成員,都不再影響已經(jīng)實(shí)例化的對(duì)象了。此時(shí),對(duì)象具有了和屬性,同時(shí)具有了構(gòu)造函數(shù)的原型對(duì)象的所有成員,當(dāng)然,此時(shí)該原型對(duì)象是沒(méi)有成員的。 前言 本篇文章用來(lái)記錄下最近研究對(duì)象的一些心得,做一個(gè)記錄與總結(jié),以加深自己的印象,同時(shí),希望也能給正在學(xué)習(xí)中的你一點(diǎn)啟發(fā)。本文適合有一定JavaScript基礎(chǔ)的童鞋閱讀。原文戳這...
摘要:后端知識(shí)點(diǎn)總結(jié)基礎(chǔ)不是是一種軟件開(kāi)發(fā)平臺(tái),它的競(jìng)爭(zhēng)對(duì)象歷史第一次有一種語(yǔ)言可以通吃前后端網(wǎng)站阿里云鏡像版本年初年中年底最新版本功能強(qiáng)大可靠,適合大型企業(yè)級(jí)項(xiàng)目簡(jiǎn)單易用適合互聯(lián)網(wǎng)項(xiàng)目易用適合平臺(tái)性能好適合服務(wù)器端密集型項(xiàng)目不適合密集型項(xiàng)目密集 后端知識(shí)點(diǎn)總結(jié)——NODE.JS基礎(chǔ) 1.Node.js Node.js不是JS,是一種軟件開(kāi)發(fā)平臺(tái),它的競(jìng)爭(zhēng)對(duì)象JSP/PHP/ASP.NET...
摘要:你可以使用像下面這樣的代碼為上面的例子來(lái)實(shí)現(xiàn)車(chē)輛模具是福特總結(jié)原型模式在里的使用簡(jiǎn)直是無(wú)處不在,其它很多模式有很多也是基于的,這里大家要注意的依然是淺拷貝和深拷貝的問(wèn)題,免得出現(xiàn)引用問(wèn)題。 1. 簡(jiǎn)介 原型模式(Prototype pattern),用原型實(shí)例指向創(chuàng)建對(duì)象的類,使用于創(chuàng)建新的對(duì)象的類的共享原型的屬性與方法。 2. 實(shí)現(xiàn) 對(duì)于原型模式,我們可以利用JavaScript特有...
摘要:一概述是一種面向?qū)ο蟮恼Z(yǔ)言。除了基本數(shù)據(jù)類型,其他的都是對(duì)象。表示創(chuàng)建一個(gè)沒(méi)有原型的空對(duì)象。模擬操作符注意返回值訪問(wèn)對(duì)象屬性訪問(wèn)方式也就是。對(duì)象在作為值時(shí),是作為引用傳遞的。假如判斷對(duì)象是否為數(shù)組目前的很多庫(kù),中都是這樣實(shí)現(xiàn)的。 一、概述 JS是一種面向?qū)ο蟮恼Z(yǔ)言。除了基本數(shù)據(jù)類型number, string, boolean(true, false), null, undefined...
摘要:要用作原型的對(duì)象。函數(shù)對(duì)象可以創(chuàng)建普通對(duì)象,這個(gè)我們上面講過(guò)了回顧一下這是一個(gè)自定義構(gòu)造函數(shù)普通對(duì)象沒(méi)法創(chuàng)建函數(shù)對(duì)象,凡是通過(guò)創(chuàng)建的對(duì)象都是函數(shù)對(duì)象,其他都是普通對(duì)象通常通過(guò)創(chuàng)建,可以通過(guò)來(lái)判斷。 關(guān)于js的原型和原型鏈,有人覺(jué)得這是很頭疼的一塊知識(shí)點(diǎn),其實(shí)不然,它很基礎(chǔ),不信,往下看要了解原型和原型鏈,我們得先從對(duì)象說(shuō)起 創(chuàng)建對(duì)象 創(chuàng)建對(duì)象的三種方式: 對(duì)象直接量 通過(guò)對(duì)象直接量創(chuàng)建...
閱讀 2216·2021-10-08 10:15
閱讀 1262·2019-08-30 15:52
閱讀 584·2019-08-30 12:54
閱讀 1606·2019-08-29 15:10
閱讀 2748·2019-08-29 12:44
閱讀 3067·2019-08-29 12:28
閱讀 3418·2019-08-27 10:57
閱讀 2286·2019-08-26 12:24