国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

JavaScript創(chuàng)建對(duì)象的七種方式全面總結(jié)

2019-11-19 15:43:22
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

 JavaScript創(chuàng)建對(duì)象的方式有很多,通過(guò)Object構(gòu)造函數(shù)或?qū)ο笞置媪康姆绞揭部梢詣?chuàng)建單個(gè)對(duì)象,顯然這兩種方式會(huì)產(chǎn)生大量的重復(fù)代碼,并不適合量產(chǎn)。接下來(lái)介紹七種非常經(jīng)典的創(chuàng)建對(duì)象的方式,他們也各有優(yōu)缺點(diǎn)

工廠模式

function createPerson(name, job) { var o = new Object() o.name = name o.job = job o.sayName = function() {  console.log(this.name) } return o}var person1 = createPerson(‘Jiang', ‘student')var person2 = createPerson(‘X', ‘Doctor')

可以無(wú)數(shù)次調(diào)用這個(gè)工廠函數(shù),每次都會(huì)返回一個(gè)包含兩個(gè)屬性和一個(gè)方法的對(duì)象

工廠模式雖然解決了創(chuàng)建多個(gè)相似對(duì)象的問(wèn)題,但是沒(méi)有解決對(duì)象識(shí)別問(wèn)題,即不能知道一個(gè)對(duì)象的類(lèi)型

構(gòu)造函數(shù)模式

function Person(name, job) { this.name = name this.job = job this.sayName = function() {  console.log(this.name) }}var person1 = new Person(‘Jiang', ‘student')var person2 = new Person(‘X', ‘Doctor')

沒(méi)有顯示的創(chuàng)建對(duì)象,使用new來(lái)調(diào)用這個(gè)構(gòu)造函數(shù),使用new后會(huì)自動(dòng)執(zhí)行如下操作

創(chuàng)建一個(gè)新對(duì)象
這個(gè)新對(duì)象會(huì)被執(zhí)行[[prototype]]鏈接
這個(gè)新對(duì)象會(huì)綁定到函數(shù)調(diào)用的this
返回這個(gè)對(duì)象
使用這個(gè)方式創(chuàng)建對(duì)象可以檢測(cè)對(duì)象類(lèi)型

person1 instanceof Object // true
person1 instanceof Person //true
但是使用構(gòu)造函數(shù)創(chuàng)建對(duì)象,每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一次

原型模式

function Person() {}Person.prototype.name = ‘Jiang'Person.prototype.job = ‘student'Person.prototype.sayName = function() { console.log(this.name)}var person1 = new Person()

將信息直接添加到原型對(duì)象上。使用原型的好處是可以讓所有的實(shí)例對(duì)象共享它所包含的屬性和方法,不必在構(gòu)造函數(shù)中定義對(duì)象實(shí)例信息。

原型是一個(gè)非常重要的概念,在一篇文章看懂proto和prototype的關(guān)系及區(qū)別中講的非常詳細(xì)

更簡(jiǎn)單的寫(xiě)法

function Person() {}Person.prototype = { name: ‘jiang', job: ‘student', sayName: function() {  console.log(this.name) }}var person1 = new Person()

將Person.prototype設(shè)置為等于一個(gè)以對(duì)象字面量形式創(chuàng)建的對(duì)象,但是會(huì)導(dǎo)致.constructor不在指向Person了。

使用這種方式,完全重寫(xiě)了默認(rèn)的Person.prototype對(duì)象,因此 .constructor也不會(huì)存在這里

Person.prototype.constructor === Person // false

如果需要這個(gè)屬性的話(huà),可以手動(dòng)添加

function Person() {}Person.prototype = { constructor:Person name: ‘jiang', job: ‘student', sayName: function() {  console.log(this.name) }}

不過(guò)這種方式還是不夠好,應(yīng)為constructor屬性默認(rèn)是不可枚舉的,這樣直接設(shè)置,它將是可枚舉的。所以可以時(shí)候,Object.defineProperty方法

Object.defineProperty(Person.prototype, ‘constructor', { enumerable: false, value: Person})

缺點(diǎn)

使用原型,所有的屬性都將被共享,這是個(gè)很大的優(yōu)點(diǎn),同樣會(huì)帶來(lái)一些缺點(diǎn)

原型中所有屬性實(shí)例是被很多實(shí)例共享的,這種共享對(duì)于函數(shù)非常合適。對(duì)于那些包含基本值的屬性也勉強(qiáng)可以,畢竟實(shí)例屬性可以屏蔽原型屬性。但是引用類(lèi)型值,就會(huì)出現(xiàn)問(wèn)題了

function Person() {}Person.prototype = { name: ‘jiang', friends: [‘Shelby', ‘Court']}var person1 = new Person()var person2 = new Person()person1.friends.push(‘Van')console.log(person1.friends) //[“Shelby”, “Court”, “Van”]console.log(person2.friends) //[“Shelby”, “Court”, “Van”]console.log(person1.friends === person2.friends) // true

friends存在與原型中,實(shí)例person1和person2指向同一個(gè)原型,person1修改了引用的數(shù)組,也會(huì)反應(yīng)到實(shí)例person2中

組合使用構(gòu)造函數(shù)模式和原型模式

這是使用最為廣泛、認(rèn)同度最高的一種創(chuàng)建自定義類(lèi)型的方法。它可以解決上面那些模式的缺點(diǎn)

使用此模式可以讓每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性副本,但同時(shí)又共享著對(duì)方法的引用

這樣的話(huà),即使實(shí)例屬性修改引用類(lèi)型的值,也不會(huì)影響其他實(shí)例的屬性值了

function Person(name) { this.name = name this.friends = [‘Shelby', ‘Court']}Person.prototype.sayName = function() { console.log(this.name)}var person1 = new Person()var person2 = new Person()person1.friends.push(‘Van')console.log(person1.friends) //[“Shelby”, “Court”, “Van”]console.log(person2.friends) // [“Shelby”, “Court”]console.log(person1.friends === person2.friends) //false

動(dòng)態(tài)原型模式

動(dòng)態(tài)原型模式將所有信息都封裝在了構(gòu)造函數(shù)中,初始化的時(shí)候,通過(guò)檢測(cè)某個(gè)應(yīng)該存在的方法時(shí)候有效,來(lái)決定是否需要初始化原型

function Person(name, job) { // 屬性 this.name = name this.job = job
 // 方法 if(typeof this.sayName !== ‘function') {  Person.prototype.sayName = function() {    console.log(this.name)  } }}var person1 = new Person(‘Jiang', ‘Student')person1.sayName()

只有在sayName方法不存在的時(shí)候,才會(huì)將它添加到原型中。這段代碼只會(huì)初次調(diào)用構(gòu)造函數(shù)的時(shí)候才會(huì)執(zhí)行。

此后原型已經(jīng)完成初始化,不需要在做什么修改了

這里對(duì)原型所做的修改,能夠立即在所有實(shí)例中得到反映

其次,if語(yǔ)句檢查的可以是初始化之后應(yīng)該存在的任何屬性或方法,所以不必用一大堆的if語(yǔ)句檢查每一個(gè)屬性和方法,只要檢查一個(gè)就行

寄生構(gòu)造函數(shù)模式

這種模式的基本思想就是創(chuàng)建一個(gè)函數(shù),該函數(shù)的作用僅僅是封裝創(chuàng)建對(duì)象的代碼,然后再返回新建的對(duì)象

function Person(name, job) { var o = new Object() o.name = name o.job = job o.sayName = function() {  console.log(this.name) } return o}var person1 = new Person(‘Jiang', ‘student')person1.sayName()

這個(gè)模式,除了使用new操作符并把使用的包裝函數(shù)叫做構(gòu)造函數(shù)之外,和工廠模式幾乎一樣

構(gòu)造函數(shù)如果不返回對(duì)象,默認(rèn)也會(huì)返回一個(gè)新的對(duì)象,通過(guò)在構(gòu)造函數(shù)的末尾添加一個(gè)return語(yǔ)句,可以重寫(xiě)調(diào)用構(gòu)造函數(shù)時(shí)返回的值

穩(wěn)妥構(gòu)造函數(shù)模式

首先明白穩(wěn)妥對(duì)象指的是沒(méi)有公共屬性,而且其方法也不引用this。

穩(wěn)妥對(duì)象最適合在一些安全環(huán)境中(這些環(huán)境會(huì)禁止使用this和new),或防止數(shù)據(jù)被其他應(yīng)用程序改動(dòng)時(shí)使用

穩(wěn)妥構(gòu)造函數(shù)模式和寄生模式類(lèi)似,有兩點(diǎn)不同:一是創(chuàng)建對(duì)象的實(shí)例方法不引用this,而是不使用new操作符調(diào)用構(gòu)造函數(shù)

function Person(name, job) { var o = new Object() o.name = name o.job = job o.sayName = function() {  console.log(name) } return o}var person1 = Person(‘Jiang', ‘student')person1.sayName()

和寄生構(gòu)造函數(shù)模式一樣,這樣創(chuàng)建出來(lái)的對(duì)象與構(gòu)造函數(shù)之間沒(méi)有什么關(guān)系,instanceof操作符對(duì)他們沒(méi)有意義

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助~如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)武林網(wǎng)的支持!

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 陆河县| 乌审旗| 托克逊县| 文水县| 攀枝花市| 米易县| 华宁县| 沛县| 东阿县| 宁乡县| 布尔津县| 阿克| 兴文县| 黑水县| 四会市| 武宣县| 象山县| 荥阳市| 远安县| 黑河市| 花莲县| 城市| 姚安县| 山丹县| 华蓥市| 松原市| 张家港市| 淳化县| 沛县| 凌源市| 金堂县| 崇文区| 余庆县| 伊宁市| 邮箱| 宣汉县| 临城县| 寻乌县| 肥东县| 庆阳市| 阳泉市|