再學(xué)JS--創(chuàng)建對(duì)象的多種方式以及優(yōu)缺點(diǎn)

工廠模式

function createPerson(name) {
    var o = new Object()
    o.name = name
    o.getName = function() {
        console.log(this.name)
    }
    return o
}

var person1 = new createPerson('zhansan')

缺點(diǎn):對(duì)象無(wú)法識(shí)別,因?yàn)樗械膶?shí)例都指向一個(gè)原型

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

function createPerson(name) {
    this.name = name
    this.getName = function() {
        console.log(this.name)
    }
}

var person1 = new createPerson('zhansan')

優(yōu)點(diǎn):實(shí)例可以識(shí)別為一個(gè)特定的類型

缺點(diǎn):每次創(chuàng)建實(shí)例時(shí)搔涝,每個(gè)方法都要被創(chuàng)建一次

構(gòu)造函數(shù)優(yōu)化

function createPerson(name) {
    this.name = name
    this.getName = getName
}

function getName() {
    console.log(this)
}

var person1 = new createPerson('zhansan')

優(yōu)點(diǎn):解決了每個(gè)方法都要被重新創(chuàng)建的問(wèn)題

缺點(diǎn):封裝性不好

原型模式

function Person(name) {}

Person.prototype.name = 'zhansan'
Person.prototype.getName = function() {
    console.log(this.name)
}

var person1 = new Person()

優(yōu)點(diǎn):方法不會(huì)被重新創(chuàng)建

缺點(diǎn):所有的方法和屬性都共享、不能初始化參數(shù)

原型模式優(yōu)化1

function Person(name) {}

Person.prototype = {
    name: 'zhansan',
    getName: function() {
        console.log(this.name)
    }
}

var person1 = new Person()

優(yōu)點(diǎn):封裝性好一點(diǎn)

缺點(diǎn):重寫了原型深浮,丟失了constructor屬性

原型模式優(yōu)化2

function Person(name) {}

Person.prototype = {
    constructor: Person,
    name: 'zhansan',
    getName: function() {
        console.log(this.name)
    }
}

var person1 = new Person()

優(yōu)點(diǎn):實(shí)例可以通過(guò)constructor屬性找到所屬構(gòu)造函數(shù)

缺點(diǎn):原型模式該有的缺點(diǎn)還是有

組合模式

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

function Person(name) {
    this.name = name
}

Person.prototype = {
    constructor: Person,
    getName: function() {
        console.log(this.name)
    }
}

var person1 = new Person()

優(yōu)點(diǎn):該共享的共享笔呀,該私有的私有,使用最廣泛的方式

缺點(diǎn):封裝性不是很好

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

function Person(name) {
    this.name = name
    if(typeof this.getName != 'function') {
        Person.prototype.getName = function() {
            console.log(this.name)
        }
    }
}
var person1 = new Person('zhansan')

注意:使用動(dòng)態(tài)原型模式時(shí)斩萌,不能使用對(duì)象字面量重寫原型

function Person(name) {
    this.name = name
    if(typeof this.getName != 'function') {
        Person.prototype = {
            constructor: Person,
            getName: function() {
                console.log(this.name)
            }
        }
    }
}

var person1 = new Person('zhansan')
var person2 = new Person('lisi')
person1.getName()  // 報(bào)錯(cuò),并無(wú)該方法
person2.getName()  // 可以訪問(wèn)到

new的實(shí)現(xiàn)步驟:

  1. 首先新建一個(gè)對(duì)象
  2. 然后將對(duì)象的原型指向Person.prototype
  3. 然后Person.apply(obj)改變this指針?lè)较?/li>
  4. 返回這個(gè)對(duì)象

構(gòu)造函數(shù)的prototype屬性指向了實(shí)例的原型屏轰,使用字面量方式直接覆蓋Person.prototype颊郎,并不會(huì)更改實(shí)例的原型的值,person1依然指向以前的Person的原型霎苗,而不是Person.prototype姆吭。

如果就是想使用字面量的方式寫的話,

function Person(name) {
    this.name = name
    if(typeof this.getName != 'function') {
        Person.prototype = {
            constructor: Person,
            getName: function() {
                console.log(this.name)
            }
        }
        
        return new Person(name)
    }
}

var person1 = new Person('zhansan')
var person2 = new Person('lisi')
person1.getName()  // zhansan
person2.getName()  // lisi

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

function Person(name) {
    var o = new Object()
    o.name = name
    o.getName = function() {
        console.log(this.name)
    }
    return o
}

var person1 = new Person('zhansan')
console.log(person1 instanceof Person) // false
console.log(person1 instanceof Object) // true

這種方式可以在特殊的情況下使用唁盏,比如我們想創(chuàng)建一個(gè)具有額外方法的特殊數(shù)組内狸,但是又不想直接修改Array構(gòu)造函數(shù)

function SpecialArray() {
    var values = new Array()

    values.push.apply(values, arguments)

    values.toPipedString = function() {
        return this.join('|')
    }

    return values
}

var colors = new SpecialArray('red', 'blue', 'green')
var colors2 = SpecialArray('red2', 'blue2', 'green2')

console.log(colors)
console.log(colors.toPipedString())  //  red|blue|green
console.log(colors2)
console.log(colors2.toPipedString())  //  red2|blue2|green2

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

function person(name) {
    var o = new Object()
    o.getName = function() {
        console.log(name)
    }
    return o
}

var person1 = person('zhansan')
person1.getName() // zhansan
person1.name = 'daisy'
person1.getName() // zhansan
console.log(person1.name)  // 'daisy'

所謂穩(wěn)妥對(duì)象,指的是沒(méi)有公共屬性厘擂,而且其方法也不引用this的對(duì)象

與寄生構(gòu)造函數(shù)模式有兩點(diǎn)不同:

  1. 新創(chuàng)建的實(shí)例方法不引用this
  2. 不使用new操作符調(diào)用構(gòu)造函數(shù)

穩(wěn)妥對(duì)象最適合在一些安全的環(huán)境中昆淡。

穩(wěn)妥構(gòu)造函數(shù)模式也跟工廠模式一樣,無(wú)法識(shí)別對(duì)象所屬類型

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末刽严,一起剝皮案震驚了整個(gè)濱河市昂灵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌舞萄,老刑警劉巖眨补,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異倒脓,居然都是意外死亡撑螺,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門崎弃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)甘晤,“玉大人含潘,你說(shuō)我怎么就攤上這事“仓澹” “怎么了调鬓?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)酌伊。 經(jīng)常有香客問(wèn)我腾窝,道長(zhǎng),這世上最難降的妖魔是什么居砖? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任虹脯,我火速辦了婚禮,結(jié)果婚禮上奏候,老公的妹妹穿的比我還像新娘循集。我一直安慰自己,他們只是感情好蔗草,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布咒彤。 她就那樣靜靜地躺著,像睡著了一般咒精。 火紅的嫁衣襯著肌膚如雪镶柱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天模叙,我揣著相機(jī)與錄音歇拆,去河邊找鬼。 笑死范咨,一個(gè)胖子當(dāng)著我的面吹牛故觅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播渠啊,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼输吏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了替蛉?” 一聲冷哼從身側(cè)響起评也,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎灭返,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坤邪,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熙含,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了艇纺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怎静。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡邮弹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚓聘,到底是詐尸還是另有隱情腌乡,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布夜牡,位于F島的核電站与纽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏塘装。R本人自食惡果不足惜急迂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹦肴。 院中可真熱鬧僚碎,春花似錦、人聲如沸阴幌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)矛双。三九已至渊抽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間背零,已是汗流浹背腰吟。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留徙瓶,地道東北人毛雇。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像侦镇,于是被迫代替她去往敵國(guó)和親灵疮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348