JavaScript對(duì)象的創(chuàng)建模式與繼承模式示例講解
對(duì)象的創(chuàng)建模式
Object 構(gòu)造函數(shù)模式:先創(chuàng)建空對(duì)象,再動(dòng)態(tài)添加屬性和方法。
適用場(chǎng)景:初始時(shí)對(duì)象內(nèi)部數(shù)據(jù)不確定。
存在問(wèn)題:語(yǔ)句太多(這個(gè)問(wèn)題可以通過(guò)使用對(duì)象字面量模式來(lái)解決)。
var person = new Object() person.name = 'Tom' person.setName = function(name){ this.name = name }
使用對(duì)象字面量模式:使用 {}
創(chuàng)建對(duì)象,同時(shí)指定屬性和方法。
適用場(chǎng)景:初始時(shí)對(duì)象內(nèi)部數(shù)據(jù)是確定的。
存在問(wèn)題:如果創(chuàng)建多個(gè)對(duì)象,有很多重復(fù)代碼(這個(gè)問(wèn)題可以通過(guò)使用工廠模式來(lái)解決)。
var person={ name:'Tom', setName: function (name){ this.name = name } }
工廠模式:通過(guò)工廠函數(shù)動(dòng)態(tài)創(chuàng)建對(duì)象并返回。
適用場(chǎng)景:需要?jiǎng)?chuàng)建多個(gè)對(duì)象。
存在問(wèn)題:對(duì)象沒(méi)有具體的類型(這個(gè)問(wèn)題可以通過(guò)使用自定義構(gòu)造函數(shù)模式來(lái)解決)。
function createPerson(name) { var obj = { name: name, setName: function (name) { this.name = name } } return obj } var p1 = createPerson('Tom') var p2 = createPerson('Mary')
自定義構(gòu)造函數(shù)模式:自定義構(gòu)造函數(shù),通過(guò) new 創(chuàng)建對(duì)象。
適用場(chǎng)景:需要?jiǎng)?chuàng)建多個(gè)類型確定的對(duì)象。
存在問(wèn)題:每個(gè)對(duì)象都有相同的數(shù)據(jù)(方法),浪費(fèi)內(nèi)存(這個(gè)問(wèn)題可以通過(guò)使用構(gòu)造函數(shù) + 原型的組合模式來(lái)解決)。
function Person(name) { this.name = name this.setName = function(name) { this.name = name } } var p1 = new Person('Tom') var p2 = new Person('Mary')
構(gòu)造函數(shù) + 原型的組合模式:自定義構(gòu)造函數(shù),屬性在函數(shù)中初始化,方法添加到原型上。
適用場(chǎng)景:需要?jiǎng)?chuàng)建多個(gè)類型確定的對(duì)象。
function Person(name) { this.name = name } Person.prototype.setName = function(name) { this.name = name } var p1 = new Person('Tom') var p2 = new Person('Mary')
對(duì)象的繼承模式
原型鏈繼承:
變量查找作用域鏈;對(duì)象的屬性和方法查找原型鏈。
child.toString()
child.__proto__
= Child.prototype
----> Child.prototype
= new Object()
----> {}.__proto__
= Object.prptotype
child 能夠訪問(wèn)到 toString 方法:是因?yàn)?child 實(shí)例能夠訪問(wèn)到其原型對(duì)象上的方法;Child 構(gòu)造函數(shù)的原型對(duì)象又指向 Object 構(gòu)造函數(shù)的實(shí)例;{} 實(shí)例能夠訪問(wèn)到其原型對(duì)象上的方法,因此順著原型鏈 child 能夠訪問(wèn)到 Object 構(gòu)造函數(shù)原型對(duì)象上的方法。
// 父類型 function Parent() { this.parentProp = 'parent prop' } Parent.prototype.showParent = function() { console.log(this.parentProp) } // 子類型 function Child() { this.childProp = 'child prop' } // 讓子類構(gòu)造函數(shù)的 prototype 指向父類的實(shí)例對(duì)象,就可以形成子類 --- 父類的一條原型鏈,子類就可以訪問(wèn)到父類原型上的屬性和方法。 Child.prototype = new Parent() // 如果此時(shí) console.log(child.constructor) 會(huì)打印輸出 Parent。 // 默認(rèn)情況下,所有的原型對(duì)象都會(huì)自動(dòng)獲得一個(gè) constructor 屬性,指向原型對(duì)象所在的函數(shù)。因此 child 本身是沒(méi)有 constructor 屬性的,而是在它的原型對(duì)象身上;又因?yàn)樗脑蛯?duì)象指向了 Parent 的實(shí)例對(duì)象;Parent 實(shí)例對(duì)象的原型對(duì)象的 constructor 是 Parent,因此 child.constructor = Parent。這樣是錯(cuò)誤的。 Child.prototype.constructor = Child Child.prototype.showChild = function() { console.log(this.childProp) } var child = new Child() child.showParent()
借用構(gòu)造函數(shù)繼承:其實(shí)并沒(méi)有真的實(shí)現(xiàn)繼承,而是在子類構(gòu)造函數(shù)中通過(guò) call() 調(diào)用了父類的構(gòu)造函數(shù)。
function Parent(name, age) { this.name = name this.age = age } function Child(name, age, price) { Parent.call(this, name, age) // 相當(dāng)于執(zhí)行 this.Person(name, age),也就是相當(dāng)于 this.name = name; this.age = age this.price = price } const child = new Child('Tom', 20, 500) console.log(child.name, child.age, child.price)
組合繼承:利用原型鏈繼承實(shí)現(xiàn)對(duì)父類型的方法的繼承;借用構(gòu)造函數(shù)繼承初始化相同的屬性(真正在用的是這種方法)。
call() 是繼承屬性,重寫原型是繼承方法。
function Parent(name, age) { this.name = name this.age = age } Parent.prototype.setName = function(name) { this.name = name } function Child(name, age, price) { // 初始化相同的屬性 Parent.call(this, name, age) this.price = price } // 繼承父類的原型對(duì)象上的方法 Child.prototype = new Parent() // 修正 constructor 屬性 Child.prototype.constructor = Child Parent.prototype.setPrice = function(price) { this.price = price } const child = new Child('Tom', 20, 500) console.log(child.name, child.age, child.price)
到此這篇關(guān)于JavaScript對(duì)象的創(chuàng)建模式與繼承模式示例講解的文章就介紹到這了,更多相關(guān)JS對(duì)象創(chuàng)建模式與繼承模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
node在兩個(gè)div之間移動(dòng),用ztree實(shí)現(xiàn)
本文介紹了“node在兩個(gè)div之間移動(dòng),用ztree實(shí)現(xiàn)”的方法,需要的朋友可以參考一下2013-03-03Js判斷參數(shù)(String,Array,Object)是否為undefined或者值為空
在一些前端控件要提交數(shù)據(jù)到服務(wù)器端的數(shù)據(jù)驗(yàn)證過(guò)程中,需要判斷提交的數(shù)據(jù)是否為空。如果是普通表單的字符串?dāng)?shù)據(jù),只需要在 trim 后判斷 length 即可,而這里需要的數(shù)據(jù)可以是各種不同的類型,通過(guò) JSON.stringify(data) 進(jìn)行序列化后再傳遞2013-11-11JavaScript之class繼承_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了JavaScript之class繼承,新的關(guān)鍵字class從ES6開始正式被引入到JavaScript中。class的目的就是讓定義類更簡(jiǎn)單,有興趣的可以了解一下2017-07-07javascript面向?qū)ο蟀b類Class封裝類庫(kù)剖析
一個(gè)從來(lái)沒(méi)有接觸過(guò)javascript的技術(shù)人員,幾小時(shí)內(nèi)就可以寫出一個(gè)簡(jiǎn)單有用的程序代碼;想寫出高性能的代碼,同樣需要具備一個(gè)高級(jí)程序員的基本素養(yǎng),javascript也是如此2013-01-01JavaScript調(diào)試常見報(bào)錯(cuò)及原因分析
這篇文章主要介紹了JavaScript調(diào)試常見報(bào)錯(cuò)及原因分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04JavaScript用Number方法實(shí)現(xiàn)string轉(zhuǎn)int
parseInt方法在format'00'開頭的數(shù)字時(shí)會(huì)當(dāng)作2進(jìn)制轉(zhuǎn)10進(jìn)制,所以建議string轉(zhuǎn)int最好用Number方法2014-05-05