3-javascript 構(gòu)造函數(shù)

js中面向?qū)ο缶幊淌腔?構(gòu)造函數(shù)(consstructor)原型鏈(prototype)?的联四。

構(gòu)造函數(shù)作為對象的模板危队。所謂構(gòu)造函數(shù)讨彼,就是提供一個生成對象的模板,并描述對象的基本結(jié)構(gòu)的函數(shù)兄淫。一個構(gòu)造函數(shù),可以生成多個對象蔓姚,每個對象都有相同的結(jié)構(gòu)捕虽。


為了與普通函數(shù)區(qū)別,構(gòu)造函數(shù)名字的第一個字母通常大寫坡脐。函數(shù)體內(nèi)使用this關(guān)鍵字泄私,代表所要生成的對象實(shí)例。生成對象時备闲,必須使用new命令來調(diào)用構(gòu)造函數(shù)晌端。


object?instanceof?constructor

instanceof?運(yùn)算符用來檢測?constructor.prototype?是否存在于參數(shù)?object?的原型鏈上。


new 命令

new命令的作用就是執(zhí)行構(gòu)造函數(shù)并返回一個對象實(shí)例恬砂。執(zhí)行時 順序?yàn)椋?/p>

1咧纠、創(chuàng)建新的空對象,作為將要返回的對象實(shí)例泻骤。

2惧盹、將空對象的原型指向構(gòu)造函數(shù)的prototype屬性

3、將空對象賦值給構(gòu)造函數(shù)內(nèi)部的this關(guān)鍵字

4瞪讼、開始執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼钧椰。

基本用法

  new命令的作用,就是調(diào)用一個構(gòu)造函數(shù)符欠,并且返回一個對象實(shí)例嫡霞。

function Keith() {

? ? ? this.height = 180;

?}

var boy = new Keith();

console.log(boy.height);  //180

上面代碼中通過new命令,讓構(gòu)造函數(shù)Keith生成一個對象實(shí)例希柿,并賦值給全局變量boy诊沪。這個新生成的對象實(shí)例养筒,從構(gòu)造函數(shù)Keith中繼承了height屬性。也就說明了這個對象實(shí)例是沒有height屬性的端姚。在new命令執(zhí)行時晕粪,就代表了新生成的對象實(shí)例boy。this.height表示對象實(shí)例有一個height屬性渐裸,它的值是180巫湘。

使用new命令時,根據(jù)需要昏鹃,構(gòu)造函數(shù)也可以接受參數(shù)尚氛。

function Person(name, height) {

? ? ? ?this.name = name;

? ? ? ? this.height = height;

}

var boy = new Person('Keith', 180);

console.log(boy.name); //'Keith'

console.log(boy.height); //180

var girl = new Person('Samsara', 160);

console.log(girl.name); //'Samsara'

console.log(girl.height); //160

  用以上的一個例子,來對構(gòu)造函數(shù)的特點(diǎn)和new基本原理進(jìn)行一個梳理洞渤。

  上面代碼中阅嘶,首先,我們創(chuàng)建了一個構(gòu)造函數(shù)Person载迄,傳入了兩個參數(shù)name和height讯柔。構(gòu)造函數(shù)Person內(nèi)部使用了this關(guān)鍵字來指向?qū)⒁傻膶ο髮?shí)例。

  然后护昧,我們使用new命令來創(chuàng)建了兩個對象實(shí)例boy和girl磷杏。

  當(dāng)我們使用new來調(diào)用構(gòu)造函數(shù)時,new命令會創(chuàng)建一個空對象boy捏卓,作為將要返回的實(shí)例對象极祸。接著,這個空對象的原型會指向構(gòu)造函數(shù)Person的prototype屬性怠晴。也就是boy.prototype===Person.prototype的遥金。要注意的是空對象指向構(gòu)造函數(shù)Person的prototype屬性,而不是指向構(gòu)造函數(shù)本身蒜田。然后稿械,我們將這個空對象賦值給構(gòu)造函數(shù)內(nèi)部的this關(guān)鍵字。也就是說冲粤,讓構(gòu)造函數(shù)內(nèi)部的this關(guān)鍵字指向一個對象實(shí)例美莫。最后,開始執(zhí)行構(gòu)造函數(shù)內(nèi)部代碼梯捕。

  因?yàn)閷ο髮?shí)例boy和girl是沒有name和height屬性的厢呵,所以對象實(shí)例中的兩個屬性都是繼承自構(gòu)造函數(shù)Person中的。這也就說明了構(gòu)造函數(shù)是生成對象的函數(shù)傀顾,是給對象提供模板的函數(shù)襟铭。



  一個問題,如果我們忘記使用new命令來調(diào)用構(gòu)造函數(shù),直接調(diào)用構(gòu)造函數(shù)了寒砖,會發(fā)生什么赐劣?

這種情況下,構(gòu)造函數(shù)就變成了普通函數(shù)哩都,并不會生成實(shí)例對象魁兼。而且由于后面會說到的原因,this這時代表全局對象漠嵌,將造成一些意想不到的結(jié)果咐汞。

function Keith() {

? ? ? this.height = 180;

}

var person = Keith();

console.log(person.height); //TypeError: person is undefined

console.log(window.height); //180

  上面代碼中,當(dāng)在調(diào)用構(gòu)造函數(shù)Keith時献雅,忘記加上new命令碉考。結(jié)果是this指向了全局作用域塌计,height也就變成了全局變量挺身。而變量person變成了undefined。

因此锌仅,應(yīng)該非常小心章钾,避免出現(xiàn)不使用new命令、直接調(diào)用構(gòu)造函數(shù)的情況热芹。

為了保證構(gòu)造函數(shù)必須與new命令一起使用贱傀,一個解決辦法是,在構(gòu)造函數(shù)內(nèi)部使用嚴(yán)格模式伊脓,即第一行加上use strict府寒。

?function Person(name, height) {

? ? ? ?'use strict';

? ? ? this.name = name;

? ? ? ?this.height = height;

}

var boy = Person();

console.log(boy) //TypeError: name is undefined

上面代碼的Person為構(gòu)造函數(shù),use strict命令保證了該函數(shù)在嚴(yán)格模式下運(yùn)行报腔。由于在嚴(yán)格模式中株搔,函數(shù)內(nèi)部的this不能指向全局對象。如果指向了全局纯蛾,this默認(rèn)等于undefined纤房,導(dǎo)致不加new調(diào)用會報錯(JavaScript不允許對undefined添加屬性)。

另一個解決辦法翻诉,是在構(gòu)造函數(shù)內(nèi)部判斷是否使用new命令炮姨,如果發(fā)現(xiàn)沒有使用,則直接返回一個實(shí)例對象碰煌。

function Person(name, height) {

if (!(this instanceof Person)) {

? ? ? ? ? return new Person(name, height);

?}

this.name = name;

this.height = height;

}

var boy = Person('Keith');

console.log(boy.name) //'Keith'

上面代碼中的構(gòu)造函數(shù)舒岸,不管加不加new命令,都會得到同樣的結(jié)果芦圾。

如果構(gòu)造函數(shù)內(nèi)部有return語句吁津,而且return后面跟著一個復(fù)雜數(shù)據(jù)類型(對象,數(shù)組等),new命令會返回return語句指定的對象碍脏;如果return語句后面跟著一個簡單數(shù)據(jù)類型(字符串梭依,布爾值,數(shù)字等)典尾,則會忽略return語句役拴,返回this對象。

function Keith() {

this.height = 180;

return {

? ? ? ? ?height: 200

};

}

var boy = new Keith();

?console.log(boy.height); //200

function Keith() {

this.height = 100;

? ? ? ?return 200;

}

var boy = new Keith();

console.log(boy.height); //100

另一方面钾埂,如果對普通函數(shù)(內(nèi)部沒有this關(guān)鍵字的函數(shù))使用new命令河闰,則會返回一個空對象。

function Keith() {

? ? ?return 'this is a message';

}

var boy = new Keith();

console.log(boy); // Keith {}

上面代碼中褥紫,對普通函數(shù)Keith使用new命令姜性,會創(chuàng)建一個空對象。這是因?yàn)閚ew命令總是返回一個對象髓考,要么是實(shí)例對象部念,要么是return語句指定的對象或數(shù)組。本例中氨菇,return語句返回的是字符串儡炼,所以new命令就忽略了該語句。


構(gòu)造函數(shù)的繼承

1查蓉、構(gòu)造函數(shù)綁定:使用call或apply方法乌询,將父對象的構(gòu)造函數(shù)綁定在子對象上。

2豌研、prototype模式:使用prototype屬性瓣距。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末右冻,一起剝皮案震驚了整個濱河市刑枝,隨后出現(xiàn)的幾起案子瘫寝,更是在濱河造成了極大的恐慌,老刑警劉巖及汉,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沮趣,死亡現(xiàn)場離奇詭異,居然都是意外死亡坷随,警方通過查閱死者的電腦和手機(jī)房铭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來温眉,“玉大人缸匪,你說我怎么就攤上這事±嘁纾” “怎么了凌蔬?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵露懒,是天一觀的道長。 經(jīng)常有香客問我砂心,道長懈词,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任辩诞,我火速辦了婚禮坎弯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘译暂。我一直安慰自己抠忘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布外永。 她就那樣靜靜地躺著崎脉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伯顶。 梳的紋絲不亂的頭發(fā)上囚灼,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機(jī)與錄音砾淌,去河邊找鬼啦撮。 笑死谭网,一個胖子當(dāng)著我的面吹牛汪厨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播愉择,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼劫乱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了锥涕?” 一聲冷哼從身側(cè)響起衷戈,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎层坠,沒想到半個月后殖妇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡破花,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年谦趣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片座每。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡前鹅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出峭梳,到底是詐尸還是另有隱情舰绘,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站捂寿,受9級特大地震影響口四,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秦陋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一窃祝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧踱侣,春花似錦粪小、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至待榔,卻和暖如春逞壁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锐锣。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工腌闯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雕憔。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓姿骏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親斤彼。 傳聞我的和親對象是個殘疾皇子分瘦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容