摘要:構(gòu)造函數(shù)模式問(wèn)題每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一遍。構(gòu)造函數(shù)在不返回值的情況下,默認(rèn)會(huì)返回新對(duì)象實(shí)例。在默認(rèn)情況下,所有原型對(duì)象都會(huì)自動(dòng)獲得一個(gè)構(gòu)造函數(shù)屬性,這個(gè)屬性是一個(gè)指向?qū)傩运诤瘮?shù)的指針。。
創(chuàng)建對(duì)象的方式
1、工廠模式
在函數(shù)里,new 一個(gè) Object,然后根據(jù)傳入的參數(shù)給該對(duì)象添加屬性,最后返回該對(duì)象。問(wèn)題:無(wú)法知道一個(gè)對(duì)象的類型。
2、構(gòu)造函數(shù)模式
問(wèn)題:每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一遍。解決:在全局作用域中定義全局函數(shù)。當(dāng)然,這會(huì)導(dǎo)致封裝性很差。
3、原型模式
每個(gè)函數(shù)都有一個(gè) prototype(原型)屬性,這個(gè)屬性是一個(gè)指針,指向一個(gè)對(duì)象(指向該函數(shù)的原型對(duì)象),而這個(gè)對(duì)象的用途是包含可以由特定類型的所有實(shí)例共享的屬性和方法。如果按照字面意思來(lái)理解,那么 prototype 就是通過(guò)調(diào)用構(gòu)造函數(shù)而創(chuàng)建的那個(gè)對(duì)象實(shí)例的原型對(duì)象。使用原型對(duì)象的好處是可以讓所有對(duì)象實(shí)例共享它所包含的屬性和方法。
缺點(diǎn):原型中所有屬性是被很多實(shí)例共享的,這種共享對(duì)于函數(shù)非常合適。但是對(duì)于包含引用類型值的屬性問(wèn)題就突出了。
4、組合使用構(gòu)造函數(shù)模式和原型模式
構(gòu)造函數(shù)模式用于定義實(shí)例屬性,而原型模式用于定義方法和共享的屬性。
結(jié)果,每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本,但同時(shí)又共享著對(duì)方法的引用,最大限度地節(jié)省了內(nèi)存。另外,這種混成模式還支持向構(gòu)造函數(shù)傳遞參數(shù);可謂是集兩種模式之長(zhǎng)。
5、動(dòng)態(tài)原型模式
在構(gòu)造函數(shù)中這么寫(xiě)共享的方法和屬性:
// 方法 if (typeof this.sayName != "function") { Person.prototype.sayName = function() { alert(this.name); }; }
6、寄生構(gòu)造函數(shù)模式
基本思想:創(chuàng)建一個(gè)函數(shù),該函數(shù)的作用僅僅是封裝創(chuàng)建對(duì)象的代碼,然后再返回新創(chuàng)建的對(duì)象。
function Person(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function() { alert(this.name); }; return o; } var friend = new Person("Amy", 18, "student"); friend.sayName(); // Amy
構(gòu)造函數(shù)在不返回值的情況下,默認(rèn)會(huì)返回新對(duì)象實(shí)例。而通過(guò)在構(gòu)造函數(shù)的末尾添加一個(gè) return 語(yǔ)句,可以重寫(xiě)調(diào)用構(gòu)造函數(shù)時(shí)返回的值。
用法:這個(gè)模式可以在特殊的情況下用來(lái)為對(duì)象創(chuàng)建構(gòu)造函數(shù)。假設(shè)我們想創(chuàng)建一個(gè)具有額外方法的特殊數(shù)組。由于不能直接修改 Array 構(gòu)造函數(shù),因此可以使用這個(gè)模式。
function SpecialArray() { // 創(chuàng)建數(shù)組 var values = new Array(); // 添加值 values.push.apply(values, arguments); // 添加方法 values.toPipedString = function() { return this.join("|"); }; // 返回?cái)?shù)組 return values; } var colors = new SpecialArray("red", "green", "blue"); alert(colors.toPipedString()); // red|green|blue
關(guān)于寄生構(gòu)造函數(shù)模式,有一點(diǎn)需要說(shuō)明:
首先,返回的對(duì)象與構(gòu)造函數(shù)或者與構(gòu)造函數(shù)的原型屬性之間沒(méi)有關(guān)系;也就是說(shuō),構(gòu)造函數(shù)返回的對(duì)象與在構(gòu)造函數(shù)外部創(chuàng)建的對(duì)象沒(méi)有什么不同。為此,不能依賴 instanceof 操作符來(lái)確定對(duì)象類型。
1 創(chuàng)建一個(gè)新對(duì)象;
2 將構(gòu)造函數(shù)的作用域賦給新對(duì)象(因此 this 就指向了這個(gè)新對(duì)象);
3 執(zhí)行構(gòu)造函數(shù)中的代碼(為這個(gè)新對(duì)象添加屬性);
4 返回新對(duì)象。
理解原型對(duì)象所有函數(shù)都有一個(gè) prototype 屬性,這個(gè)屬性指向函數(shù)的原型對(duì)象。
在默認(rèn)情況下,所有原型對(duì)象都會(huì)自動(dòng)獲得一個(gè) constructor (構(gòu)造函數(shù))屬性,這個(gè)屬性是一個(gè)指向 prototype 屬性所在函數(shù)的指針。
eg. Person.prototype.constructor => Person。
當(dāng)調(diào)用構(gòu)造函數(shù)創(chuàng)建一個(gè)新實(shí)例后,該實(shí)例的內(nèi)部將包含一個(gè)指針(內(nèi)部屬性[[Prototype]]),指向構(gòu)造函數(shù)的原型對(duì)象。注意:這個(gè)連接存在于實(shí)例與構(gòu)造函數(shù)的原型對(duì)象之間,而不是存在于實(shí)例與構(gòu)造函數(shù)之間。實(shí)例 => 構(gòu)造函數(shù)的原型對(duì)象
判斷某個(gè)實(shí)例的原型指針是否指向某個(gè)函數(shù)的原型對(duì)象:
Person.prototype.isPrototypeOf(person1) // true Object.getPrototypeOf(person1) === Person.protype // true
hasOwnProperty() 方法:檢測(cè)一個(gè)屬性是存在于實(shí)例中,還是存在于原型中。只有存在于實(shí)例中時(shí),才返回 true。
in 操作符:實(shí)例和原型中的屬性都能訪問(wèn)到。
同時(shí)使用 hasOwnProperty() 方法和 in 操作符,就可以確定該屬性到底是存在于對(duì)象中,還是存在于原型中。
Object.keys() 方法:取得對(duì)象上所有可枚舉的實(shí)例屬性。 Object.getOwnPropertyNames() 方法:得到所有實(shí)例屬性(包括不可枚舉屬性)。重寫(xiě)原型會(huì)怎么樣?
Person.prototype = {…}:
我們將 Person.prototype 設(shè)置為等于一個(gè)以對(duì)象字面量形式創(chuàng)建的新對(duì)象。 最終結(jié)果相同,但有一個(gè)例外:constructor 屬性不再指向 Person 了。前面曾經(jīng)介紹過(guò),每創(chuàng)建一個(gè)函數(shù),就會(huì)同時(shí)創(chuàng)建它的 prototype 對(duì)象,這個(gè)對(duì)象也會(huì)自動(dòng)獲得 constructor 屬性。而我們?cè)谶@里使用的語(yǔ)法,本質(zhì)上完全重寫(xiě)了默認(rèn)的 prototype 對(duì)象,因此 constructor 屬性也就變成了新對(duì)象的 constructor 屬性(指向 Object 構(gòu)造函數(shù)),不再指向 Person 函數(shù)。此時(shí),盡管 instanceof 操作符還能返回正確的結(jié)果,但通過(guò) constructor 已經(jīng)無(wú)法確定對(duì)象的類型了。
1、原型鏈繼承
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/95130.html
摘要:前言最近參加了幾場(chǎng)面試,積累了一些高頻面試題,我把面試題分為兩類,一種是基礎(chǔ)試題主要考察前端技基礎(chǔ)是否扎實(shí),是否能夠?qū)⑶岸酥R(shí)體系串聯(lián)。 前言 最近參加了幾場(chǎng)面試,積累了一些高頻面試題,我把面試題分為兩類,一種是基礎(chǔ)試題: 主要考察前端技基礎(chǔ)是否扎實(shí),是否能夠?qū)⑶岸酥R(shí)體系串聯(lián)。一種是開(kāi)放式問(wèn)題: 考察業(yè)務(wù)積累,是否有自己的思考,思考問(wèn)題的方式,這類問(wèn)題沒(méi)有標(biāo)準(zhǔn)答案。 基礎(chǔ)題 題目的答...
摘要:筆者作為一位,將工作以來(lái)用到的各種優(yōu)秀資料神器及框架整理在此,畢竟好記性不如爛鍵盤(pán),此前端知識(shí)點(diǎn)大百科全書(shū)前端掘金,,不定期更新技巧前端掘金技巧,偶爾更新。計(jì)算數(shù)組的極值技巧使你的更加專業(yè)前端掘金一個(gè)幫你提升技巧的收藏集。 CSS 樣式畫(huà)各種圖形 - 前端 - 掘金下面是一些我在 CSS 中經(jīng)常用到的圖案,還有一些是在css-tricks看到的。記錄一下,以后會(huì)用到。會(huì)持續(xù)更新… 一、...
摘要:筆者作為一位,將工作以來(lái)用到的各種優(yōu)秀資料神器及框架整理在此,畢竟好記性不如爛鍵盤(pán),此前端知識(shí)點(diǎn)大百科全書(shū)前端掘金,,不定期更新技巧前端掘金技巧,偶爾更新。計(jì)算數(shù)組的極值技巧使你的更加專業(yè)前端掘金一個(gè)幫你提升技巧的收藏集。 CSS 樣式畫(huà)各種圖形 - 前端 - 掘金下面是一些我在 CSS 中經(jīng)常用到的圖案,還有一些是在css-tricks看到的。記錄一下,以后會(huì)用到。會(huì)持續(xù)更新… 一、...
平日學(xué)習(xí)接觸過(guò)的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...
閱讀 3538·2021-11-18 10:02
閱讀 3787·2021-09-13 10:25
閱讀 1977·2021-07-26 23:38
閱讀 2665·2019-08-30 15:44
閱讀 2361·2019-08-30 13:51
閱讀 1282·2019-08-26 11:35
閱讀 2335·2019-08-26 10:29
閱讀 3503·2019-08-23 14:56