摘要:一工廠模式創(chuàng)建對(duì)象交給一個(gè)工廠方法來(lái)實(shí)現(xiàn),可以傳遞參數(shù),但主要缺點(diǎn)是無(wú)法識(shí)別對(duì)象類型,因?yàn)閯?chuàng)建對(duì)象都是使用的原生構(gòu)造函數(shù)來(lái)完成的。此外,組合模式還支持向構(gòu)造函數(shù)傳遞參數(shù),可謂是集兩家之所長(zhǎng)。
原文鏈接
面向?qū)ο蟮恼Z(yǔ)言有一個(gè)標(biāo)志,即擁有類的概念,抽象實(shí)例對(duì)象的公共屬性與方法,基于類可以創(chuàng)建任意多個(gè)實(shí)例對(duì)象,一般具有封裝、繼承、多態(tài)的特性!
但JS中對(duì)象與純面向?qū)ο笳Z(yǔ)言中的對(duì)象是不同的,ECMA標(biāo)準(zhǔn)定義JS中對(duì)象:無(wú)序?qū)傩缘募?,其屬性可以包含基本值、?duì)象或者函數(shù)。
可以簡(jiǎn)單理解為JS的對(duì)象是一組無(wú)序的值,其中的屬性或方法都有一個(gè)名字,根據(jù)這個(gè)名字可以訪問相映射的值(值可以是基本值/對(duì)象/方法)。
一、工廠模式創(chuàng)建對(duì)象交給一個(gè)工廠方法來(lái)實(shí)現(xiàn),可以傳遞參數(shù),但主要缺點(diǎn)是無(wú)法識(shí)別對(duì)象類型,因?yàn)閯?chuàng)建對(duì)象都是使用Object的原生構(gòu)造函數(shù)來(lái)完成的。
function createPerson(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.getName = function () { return this.name; } return o; // 使用return返回生成的對(duì)象實(shí)例 } var person = createPerson("Jack", 19, "SoftWare Engineer");二、構(gòu)造函數(shù)模式
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.getName = function () { return this.name; } } var person1 = new Person("Jack", 19, "SoftWare Engineer"); var person2 = new Person("Liye", 23, "Mechanical Engineer");
構(gòu)造函數(shù)模式與工廠方法區(qū)別在于:
沒有顯式地創(chuàng)建對(duì)象
直接將屬性和方法賦值給this對(duì)象
沒有return語(yǔ)句
上述由Person構(gòu)造函數(shù)生成的兩個(gè)對(duì)象person1與person2都是Person的實(shí)例,因此可以使用instanceof判斷,并且因?yàn)樗袑?duì)象都繼承Object,因此person1 instanceof Object也返回真:
console.log(person1 instanceof Person); // true; console.log(person2 instanceof Person); // true; console.log(person1 instanceof Object); // true; console.log(person2 instanceof Object); // true; console.log(person1.constructor === person2.constructor); // ture;
雖然構(gòu)造函數(shù)方式比較不錯(cuò),但也存在缺點(diǎn),那就是在創(chuàng)建對(duì)象時(shí),特別針對(duì)對(duì)象的屬性指向函數(shù)時(shí),會(huì)重復(fù)的創(chuàng)建函數(shù)實(shí)例,以上述代碼為基礎(chǔ),可以改寫為:
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.getName = getName; } function getName() { return this.name; }三、原型模式
JS中每個(gè)函數(shù)都有一個(gè)prototype(原型)屬性,這個(gè)屬性是一個(gè)指針,指向一個(gè)對(duì)象,它是所有通過(guò)new操作符使用函數(shù)創(chuàng)建的實(shí)例的原型對(duì)象。
原型對(duì)象最大特點(diǎn)是,所有對(duì)象實(shí)例共享它所包含的屬性和方法,也就是說(shuō),所有在原型對(duì)象中創(chuàng)建的屬性或方法都直接被所有對(duì)象實(shí)例共享。
function Person() {} Person.prototype.name = "Jack"; Person.prototype.age = 29; Person.prototype.getName = function () { return this.name; } var person1 = new Person(); var person2 = new Person(); console.log(person1.getName === person2.getName); // ture;四、組合構(gòu)造函數(shù)及原型模式
目前最為常用的定義類型方式,是組合構(gòu)造函數(shù)模式與原型模式。
構(gòu)造函數(shù)模式用于定義實(shí)例的屬性,而原型模式用于定義方法和共享的屬性。
這樣,每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本,但同時(shí)又共享著對(duì)方方法的引用,最大限度的節(jié)約內(nèi)存。此外,組合模式還支持向構(gòu)造函數(shù)傳遞參數(shù),可謂是集兩家之所長(zhǎng)。
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.lessons = ["Math", "Physics"]; } Person.prototype = { constructor: Person, // 原型字面量方式會(huì)將對(duì)象的constructor變?yōu)镺bject,需要強(qiáng)制指回Person getName: function () { return this.name; } } var person1 = new Person("Jack", 19, "SoftWare Engneer"); person1.lessons.push("Biology"); var person2 = new Person("Lily", 39, "Mechanical Engneer"); console.log(person1.lessons); // ["Math", "Physics", "Biology"] console.log(person2.lessons); // ["Math", "Physics"] console.log(person1.getName === person2.getName); // true五、動(dòng)態(tài)原型模式
組合模式中實(shí)例屬性與共享方法(由原型定義)是分離的,這與純面向?qū)ο笳Z(yǔ)言不太一致。
動(dòng)態(tài)原型模式將所有構(gòu)造信息都封裝在構(gòu)造函數(shù)中,同時(shí)又保持了組合的優(yōu)點(diǎn)。
其原理就是通過(guò)判斷構(gòu)造函數(shù)的原型中是否已經(jīng)定義了共享的方法或?qū)傩裕绻麤]有則定義,否則不再執(zhí)行定義過(guò)程。
該方式只定義一次原型上方法或?qū)傩裕覍⑺袠?gòu)造過(guò)程都封裝在構(gòu)造函數(shù)中,對(duì)原型所做的修改能立即體現(xiàn)所有實(shí)例中:
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.lessons = ["Math", "Physics"]; } if (typeof this.getName) { Person.prototype = { constructor: Person, // 原型字面量方式會(huì)將對(duì)象的constructor變?yōu)镺bject,需要強(qiáng)制指回Person getName: function () { return this.name; } } } var person1 = new Person("Jack", 19, "SoftWare Engneer"); person1.lessons.push("Biology"); var person2 = new Person("Lily", 39, "Mechanical Engneer"); console.log(person1.lessons); // ["Math", "Physics", "Biology"] console.log(person2.lessons); // ["Math", "Physics"] console.log(person1.getName === person2.getName); // true
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/81854.html
摘要:構(gòu)造函數(shù)模式是中最常用的模式之一,用于創(chuàng)建給定類型的新對(duì)象。原型模式這是基于對(duì)象的創(chuàng)造型設(shè)計(jì)模式。它通常用于目標(biāo)對(duì)象受到約束且可能無(wú)法有效地處理其所有職責(zé)的情況。它不是構(gòu)造函數(shù)其靜態(tài)方法用于可攔截的操作。 showImg(https://segmentfault.com/img/bVbwdpt?w=700&h=340); 原文:https://medium.com/better-pro...
摘要:想繼續(xù)了解設(shè)計(jì)模式必須要先搞懂面向?qū)ο缶幊?,否則只會(huì)讓你自己更痛苦。創(chuàng)建型設(shè)計(jì)模式主要有簡(jiǎn)單工廠模式,工廠方法模式,抽象工廠模式,建造者模式,原型模式和單例模式,下面一一道來(lái)。而工廠方法模式本意是將實(shí)際創(chuàng)建對(duì)象的工作推遲到子類中。 接觸前端兩三個(gè)月的時(shí)候,那時(shí)候只是聽說(shuō)設(shè)計(jì)模式很重要,然后我就去讀了一本設(shè)計(jì)模式的書,讀了一部分,也不知道這些設(shè)計(jì)模式到底設(shè)計(jì)出來(lái)干嘛的,然后就沒再看了。后...
摘要:使用構(gòu)造函數(shù)的原型繼承相比使用原型的原型繼承更加復(fù)雜,我們先看看使用原型的原型繼承上面的代碼很容易理解。相反的,使用構(gòu)造函數(shù)的原型繼承像下面這樣當(dāng)然,構(gòu)造函數(shù)的方式更簡(jiǎn)單。 五天之前我寫了一個(gè)關(guān)于ES6標(biāo)準(zhǔn)中Class的文章。在里面我介紹了如何用現(xiàn)有的Javascript來(lái)模擬類并且介紹了ES6中類的用法,其實(shí)它只是一個(gè)語(yǔ)法糖。感謝Om Shakar以及Javascript Room中...
摘要:個(gè)人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現(xiàn)在已經(jīng)一年的時(shí)間了,由于工作比較忙,更新緩慢,后面還是會(huì)繼更新,現(xiàn)將已經(jīng)寫好的文章整理一個(gè)目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個(gè)人前端文章整理 從最開始萌生寫文章的想法,到著手...
閱讀 3122·2021-09-22 15:18
閱讀 3546·2019-08-30 15:54
閱讀 3399·2019-08-30 15:53
閱讀 733·2019-08-30 14:12
閱讀 977·2019-08-29 17:01
閱讀 2342·2019-08-29 14:04
閱讀 1564·2019-08-29 13:09
閱讀 990·2019-08-26 17:40