簡單介紹js中構(gòu)造函數(shù) 原型 原型鏈(一)

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

在ECMAScript中的構(gòu)造函數(shù)可用來創(chuàng)建特定類型的對象。像Object Array這樣的原生的構(gòu)造函數(shù) 在運行時會自動出現(xiàn)在運行環(huán)境中。 當然 我們也可以創(chuàng)建自定義的構(gòu)造函數(shù)袍啡, 從而定義自定義對象類型的屬性和方法。
例如:

function Person(name, age, job) {
      this.name = name;
      this.age = age;
      this.job = job;
      this.sayName = function() {
        alert(this.name)
    };
}
var person1 = new Person("張三"瞬逊, 18檐迟,"工人");
var person2 = new Person("李四"码耐, 25追迟, "包工頭")

在這個例子中, 我們可以看到與正常函數(shù)的一些不同之處:

1.沒有顯式地創(chuàng)建對象骚腥;
2.直接將屬性和方法賦給了this對象敦间;
3. 沒有return 語句。

此外 我們還注意到函數(shù)名Person的首字母是大寫的束铭,按照慣例 廓块,構(gòu)造函數(shù)的首字母是大寫的 而非構(gòu)造函數(shù)的首字母是不大寫的。
要創(chuàng)建Person函數(shù)的新實例契沫, 必須使用new 操作符带猴。 以這種方式調(diào)用構(gòu)造函數(shù)會經(jīng)歷以下四個步驟:

1.創(chuàng)建一個新對象;
2.將構(gòu)造函數(shù)的作用域賦給新對象(因此this就指向了這個新對象懈万;
3. 執(zhí)行構(gòu)造函數(shù)中的代碼(為這個新對象添加新屬性)拴清;
4.返回新對象。

在前面例子的最后会通,person1和person2分別保存著Person的一個不同的實例口予。 這兩個對象都有一個constructor(構(gòu)造函數(shù)屬性),都指向了Person涕侈,如下所示

console.log(person1.constructor === Person);//返回true
console.log(person2.constructor === Person);//返回true

對象的constructor屬性最初是用來標識對象類型的沪停。 但是提到檢測對象類型,還是使用 instanceof操作符更加可靠一些裳涛。我們在這個例子中創(chuàng)建的所有對象既是Object的實例 也是Person的實例木张,這一點通過instanceof操作符可以得到驗證。

console.log(person1 instanceof Object)//返回true
console.log(person1 instanceof Person)//返回true
console.log(person2 instanceof Object)//返回true
console.log(person1 instanceof Person)//返回true
創(chuàng)建自定義的構(gòu)造函數(shù)意味著將來可以將它的實例標識作為一種特定的類型端三,而這正是構(gòu)造函數(shù)模式勝過工廠模式的地方舷礼。

在這個例子中, 之所以person1和person2都是Object的實例技肩,是因為所有對象均繼承自O(shè)bject且轨。
構(gòu)造函數(shù)和其他函數(shù)的唯一區(qū)別浮声, 就是在于調(diào)用他們的方式不同虚婿。但是構(gòu)造函數(shù)也是函數(shù), 不存在定義構(gòu)造函數(shù)的特殊語法泳挥。 任何函數(shù)然痊,只要通過new操作符來調(diào)用,那它就可以作為構(gòu)造函數(shù)屉符, 而且任何函數(shù)剧浸,不通過new 操作符來調(diào)用锹引, 它就是普通函數(shù)。例如 前面的例子就可以通過以下任何一種方式來調(diào)用:

//當作普通函數(shù)來調(diào)用:
  Person("柳白猿"唆香, 25嫌变,"箭士");//添加到了window上面躬它;
  window.sayName(); // 返回柳白猿腾啥;

//當作構(gòu)造函數(shù)來調(diào)用:
  var person = new Person("孫悟空", 500冯吓, "行者")倘待;
  person.sayName();// 孫悟空;

//在另一個對象的作用域中調(diào)用
var o = new Object();
Person.call(o,"八戒"组贺, 1000凸舵, "使者");
o.sayName ()//八戒

構(gòu)造函數(shù)的問題

構(gòu)造函數(shù)雖然好用失尖,但也并非沒有缺點啊奄。使用構(gòu)造函數(shù)的主要問題,就是每個方法都要在每個實例上重新創(chuàng)建一遍掀潮。在前面的例子中 person1和person2都有一個名為名為sayName的方法增热,但那個方法不是同一個Function的實例。函數(shù)也是對象胧辽, 因此每定義一個函數(shù)峻仇,就是實例化了一個對象。所以不同實例上的同名函數(shù)是不相等的邑商, 以下代碼可以證明這一點摄咆。

console.log(person1.sayName ===person2.sayName)//返回false

然而 創(chuàng)建兩個完成同樣任務的Function的實例的確沒必要。況且有this對象在人断, 根本不用在執(zhí)行代碼前就把函數(shù)綁定到特定對象的上面吭从。因此,大可以像下面這樣恶迈,通過函數(shù)定義轉(zhuǎn)移到構(gòu)造函數(shù)外邊來解決這個問題涩金。

function Person(name, age,job) {
  this.name  = name;
  this,age = age;
  this.job = job;
  this.sayName = sayName;
}
function sayName() {
  console.log(this.name);
}
var person1 = new Person('心猿意馬', 1500暇仲, '不明')步做;
var person2 = new Person('覆水難收', 2000奈附, '所以')全度;

在這個例子中, 我們把sayName()函數(shù)的定義轉(zhuǎn)移到了構(gòu)造函數(shù)外部斥滤。 而在構(gòu)造函數(shù)內(nèi)部将鸵,我們把sayName的屬性設(shè)置成等于全局的sayName函數(shù)勉盅。這樣一來,由于sayName包含的是一個指向函數(shù)的指針顶掉, 因此person1和person2對象就共享了在全局作用域中定義的同一個sayName()函數(shù)草娜。這樣做確實解決了兩個函數(shù)做同一件事的問題,可是新的問題又來了痒筒,在全局作用域中驱还,定義的函數(shù)是實際上只能被某個函數(shù)調(diào)用,這讓全局作用域有些名不副實凸克。而更讓人無法接受的是议蟆,如果對象需要定義很多的方法,那么就要定義很多個全局函數(shù)萎战,于是我們這個自定義的引用類型就毫無意義可言了咐容。 好在, 我們可以通過使用原型模式很好地解決這個問題蚂维。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末戳粒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子虫啥,更是在濱河造成了極大的恐慌蔚约,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涂籽,死亡現(xiàn)場離奇詭異苹祟,居然都是意外死亡评雌,警方通過查閱死者的電腦和手機树枫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來景东,“玉大人砂轻,你說我怎么就攤上這事〗锿拢” “怎么了搔涝?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長和措。 經(jīng)常有香客問我庄呈,道長,這世上最難降的妖魔是什么臼婆? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任抒痒,我火速辦了婚禮,結(jié)果婚禮上颁褂,老公的妹妹穿的比我還像新娘故响。我一直安慰自己,他們只是感情好颁独,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布彩届。 她就那樣靜靜地躺著,像睡著了一般誓酒。 火紅的嫁衣襯著肌膚如雪樟蠕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天靠柑,我揣著相機與錄音寨辩,去河邊找鬼。 笑死歼冰,一個胖子當著我的面吹牛靡狞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播隔嫡,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼甸怕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了腮恩?” 一聲冷哼從身側(cè)響起梢杭,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秸滴,沒想到半個月后武契,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡荡含,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年吝羞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片内颗。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡钧排,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出均澳,到底是詐尸還是另有隱情恨溜,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布找前,位于F島的核電站糟袁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏躺盛。R本人自食惡果不足惜项戴,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望槽惫。 院中可真熱鬧周叮,春花似錦辩撑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至项贺,卻和暖如春君躺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背开缎。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工棕叫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奕删。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓俺泣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親急侥。 傳聞我的和親對象是個殘疾皇子砌滞,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

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