JS隨寫:原型及原型鏈

原型鏈這個話題算是老生常談了,隨意一搜疾渣,網(wǎng)上大把文章來論述這個話題⊙缕看懂是一回事,理解是一回事杈女,自己寫出自己的理解又是另外一回事兒了朱浴。本文僅作為我在漫漫JS之路上的一點小理解和學習記錄吊圾,以備來日翻閱和深入更新。

知識準備

先給個經(jīng)典的person構(gòu)造函數(shù):

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        console.log(this.name);
    };
}

var person1 = new Person("liyang", 26, "programmer");
var person2 = new Person("xiaoming", 24, "designer");
  1. 在js中翰蠢,萬物皆對象项乒,原型 Person.prototype 也是對象。
  2. 理解 構(gòu)造函數(shù)梁沧、實例原型的概念檀何。

構(gòu)造函數(shù) : 構(gòu)造函數(shù)其實就是函數(shù),但任何函數(shù)如果使用 new 操作符來調(diào)用廷支,那它就可以作為構(gòu)造函數(shù)频鉴;而任何函數(shù),如果不通過 new 操作符來調(diào)用恋拍,那它跟普通函數(shù)也不會有什么兩樣垛孔。按照慣例,構(gòu)造函數(shù)始終都應(yīng)該以一個大寫字母開頭施敢,而非構(gòu)造函數(shù)則應(yīng)該使用一個小寫字母開頭周荐。

// 當作構(gòu)造函數(shù)使用
var person = new Person("liyang", 26, "programmer");
person.sayName(); // "liyang"

// 作為普通函數(shù)調(diào)用
Person("xiaoming", 24, "designer); // 添加到 window
window.sayName(); // "xiaoming"

// 在另一個對象的作用域中調(diào)用
var o = new Object();
Person.call(o, "Tommy", 3, "Baby");
o.sayName(); // "Tommy"

實例 :使用 new 操作符來創(chuàng)建Person的新實例 person1person2

var person1 = new Person("liyang", 26, "programmer");
var person2 = new Person("xiaoming", 24, "designer");

原型 : 簡單來說僵娃, Person.prototype 就是Person原型概作。注意,原型也是對象默怨,且 所有函數(shù)的默認原型都是Object的實例 讯榕,所以 Person.prototype 同時也是Object的一個實例。

理解原型對象

先來捋一遍最基礎(chǔ)的流程:函數(shù)一創(chuàng)建先壕,就會按照一組特定的規(guī)則(暫時搞不清)來給這個函數(shù)創(chuàng)建一個 prototype 屬性瘩扼,其實就是函數(shù) Person() 創(chuàng)建了,它的原型 Person.prototype 就有了垃僚。我們再來new一個Person的實例 person1:

var person1 = new Person("liyang", 26, "programmer");

實例person1的內(nèi)部會包含一個官方ECMA5稱為 [[Prototype]] 集绰,F(xiàn)irefox、Safari和Chrome稱為 __proto__ 的指針谆棺,而這個指針 __proto__ 就會指向構(gòu)造函數(shù)的原型對象 Person.prototype 栽燕,注意:這個指向是存在于實例 person1 和 原型對象 Person.prototype 之間的,跟構(gòu)造函數(shù) Person() 是沒半毛錢關(guān)系的改淑。

其實到現(xiàn)在碍岔,原型鏈的基礎(chǔ)知識已經(jīng)搞定1/3了,好朵夏,現(xiàn)在我們擴展一下:實例 person1 有一個 __proto__ 的指針指向了原型對象 Person.prototype 蔼啦,前面說過原型也是個實例,那它同樣也會有個 __proto__ 的指針仰猖,指向了誰呢捏肢?指向了 Object.prototype 這個原型奈籽。最后 Object.prototype 原型的 __proto__ 指向了原型鏈的終點 null 。 網(wǎng)上盜圖一波:

01.jpg

why原型?

為什么要用原型鸵赫?因為使用原型可以讓所有對象的實例共享它所包含的屬性和方法衣屏,先來個代碼:

function Person(){}

Person.prototype.name = "xiaohong";
Person.prototype.age = 25;
Person.prototype.job = "teacher";
Person.prototype.sayName = function(){
    console.log(this.name);
};

var person1 = new Person();
person1.sayName();   // "xiaohong"

var person2 = new Person();
person2.sayName();   // "xiaohong"

console.log(person1.sayName == person2.sayName);  // true

'
當調(diào)用 person1.sayName() 的時候,解析器會先在person1里找辩棒,找不到的話就接著在上面的 Person.prototype 里找狼忱,找到就返回,找不到就接著往上一睁,在 Object.prototype 里面找钻弄,這樣一級一級的找下去。

上面說的這些卖局,是為了簡單讓你入個門斧蜕,讓你有原型鏈的一個感覺,它就像是門縫里透出來的一絲光亮砚偶,能引導你推開原型鏈這個知識點的大門批销。

雜七雜八

  1. Person.prototype.construtor === Person; //ture
  2. 使用 hasOwnProperty() 檢測一個屬性是存在于實例中,還是存在于原型中染坯。
    Person.name = "xiaohong"; //ture name屬性可訪問到
    Person.hasOwnProperty("name"); //false name屬性不在實例中
  3. 實例重新定義屬性會屏蔽原型屬性均芽,可使用 delete 操作符刪除實例屬性,但不可刪除原型上的屬性单鹿。
  4. 若以對象字面量的方式來封裝原型的功能掀宋,那么就相當于重寫了整個原型對象,constructor屬性指向?qū)淖冎俪梢酝ㄟ^屬性設(shè)置將constructor屬性重新指向劲妙,此時constructor屬性將會[[Enumerable]]可枚舉(默認原生constructor不可枚舉)。
function Person(){}
var person1 = new Person();  //重寫原型對象之前實例化
Person.prototype = {
    construtor: Person,  //重新指向Person
    name: 'xiaowang',
    age:'30',
    sayName: function(){
        alert(this.name);
    }
};
var person2 = new Person();  //重寫原型對象之后實例化
  1. 若如上重寫原型對象儒喊,會切斷現(xiàn)有原型與任何之前已經(jīng)存在的對象實例之間的聯(lián)系镣奋,所以必須在其之后再創(chuàng)建實例。
    console.log(person1.name); //undefined
    console.log(person2.name); //xiaowang
  2. 讓原型對象等于另一個類型的實例怀愧,來實現(xiàn)原型鏈的 繼承 侨颈。
    son.prototype = new Father() //將son的原型作為Father()的實例
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市芯义,隨后出現(xiàn)的幾起案子哈垢,更是在濱河造成了極大的恐慌,老刑警劉巖扛拨,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耘分,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機陶贼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進店門啤贩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來待秃,“玉大人拜秧,你說我怎么就攤上這事≌掠簦” “怎么了枉氮?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長暖庄。 經(jīng)常有香客問我聊替,道長,這世上最難降的妖魔是什么培廓? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任惹悄,我火速辦了婚禮,結(jié)果婚禮上肩钠,老公的妹妹穿的比我還像新娘泣港。我一直安慰自己,他們只是感情好价匠,可當我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布当纱。 她就那樣靜靜地躺著,像睡著了一般踩窖。 火紅的嫁衣襯著肌膚如雪坡氯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天洋腮,我揣著相機與錄音箫柳,去河邊找鬼。 笑死啥供,一個胖子當著我的面吹牛悯恍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播滤灯,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼坪稽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鳞骤?” 一聲冷哼從身側(cè)響起窒百,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎豫尽,沒想到半個月后篙梢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡美旧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年渤滞,在試婚紗的時候發(fā)現(xiàn)自己被綠了贬墩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡妄呕,死狀恐怖陶舞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绪励,我是刑警寧澤肿孵,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站疏魏,受9級特大地震影響停做,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜大莫,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一蛉腌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧只厘,春花似錦烙丛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至介评,卻和暖如春库北,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背们陆。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工寒瓦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坪仇。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓杂腰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親椅文。 傳聞我的和親對象是個殘疾皇子喂很,可洞房花燭夜當晚...
    茶點故事閱讀 45,442評論 2 359

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