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