摘要:數(shù)組的構(gòu)造函數(shù)是原型鏈的指向與其他除以外的構(gòu)造函數(shù)相同,的也指向頂級原型對象,每一個數(shù)組都是的實例,都指向。實例對象查找構(gòu)造函數(shù)原型對象的方法一般會把對象共有的屬性和方法都放在構(gòu)造函數(shù)的原型對象上。
閱讀原文
在 JavaScript 中有種說法叫 “萬物皆對象”,就是說無論是構(gòu)造函數(shù)創(chuàng)建的實例,構(gòu)造函數(shù)本身、原型對象、數(shù)組、函數(shù)本質(zhì)上都是對象,都擁有 __proto__ 屬性,即隱式原型,所有函數(shù)都擁有 prototype 屬性,即顯式原型(僅限函數(shù)),原型對象(prototype 屬性指向的對象),在定義函數(shù)時就被創(chuàng)建。
原型鏈指向概述在 JavaScript 中整個原型鏈及查找機制用下圖可以完整的表示出來:
原型鏈指向:
1、通過字面量和 new Object() 所創(chuàng)建的對象,他們是構(gòu)造函數(shù)是 function Object() 的實例,Object 構(gòu)造函數(shù)的 prototype 指向原型對象 Object.prototype,Object.prototype 的 constructor 指向構(gòu)造函數(shù) Object,而實例的 __proto__ 也指向 Object.prototype,Object.prototype 的 __proto__ 指向 null,所以 Object.prototype 也叫做頂級原型對象。
2、上圖中 new Foo() 創(chuàng)建的對象是構(gòu)造函數(shù) function Foo() 的實例,Foo 的 prototype 指向原型對象 Foo.prototype,Foo.prototype 的 constructor 指向構(gòu)造函數(shù) Foo,而實例的 __proto__ 也指向 Foo.prototype,并且 Foo.prototype 雖然是原型對象,但也是對象,所以是構(gòu)造函數(shù) Object 的實例,__proto__ 指向頂級原型對象 Object.prototype。
3、數(shù)組的構(gòu)造函數(shù)是 function Array() 原型鏈的指向與其他除 Object 以外的構(gòu)造函數(shù)相同,Array.prototype 的 __proto__ 也指向頂級原型對象 Object.prototype,每一個數(shù)組都是 Array 的實例,__proto__ 都指向 Array.prototype。
4、Object、Array、Foo 等構(gòu)造函數(shù)的本質(zhì)也是對象,他們的構(gòu)造函數(shù)是 function Function(),Function 的 prototype 指向 Function.prototype,Function.prototype 的 constructor 指向 Function,所有的構(gòu)造函數(shù)的 __proto__ 都指向 Function.prototype,包括 Function 本身,也就是說構(gòu)造函數(shù) Function 是由自己構(gòu)造的,Function.prototype 的 __proto__ 同樣指向頂級原型對象 Object.prototype。
prototype 原型對象prototype 是函數(shù)的一個屬性,屬性的值指向了一個對象,所以,只有函數(shù)才有 prototype 原型對象。
function Person(name, age) { this.name = name; this.age = age; } typeof Person.prototype; // object Person.prototype.constructor; // Person {} Person.prototype.job = "qianduan"; var p1 = new Person("panda", 18); var p2 = new Person("shen", 20); p1.constructor.prototype; // 實例對象查找構(gòu)造函數(shù)原型對象的方法
一般會把對象共有的屬性和方法都放在構(gòu)造函數(shù)的原型對象上。
實例、構(gòu)造函數(shù)、原型對象的關(guān)系構(gòu)造函數(shù)的原型 prototype 屬性指向一個原型對象,實例也可以通過 __proto__ 指向原型對象,但本質(zhì)上實例和構(gòu)造函數(shù)之間是沒有關(guān)系的。
function Person(name, age) { this.name = name; this.age = age; } var p = new Person("nihao", 16); p.constructor = { name: "haha" }; p.name; // nihao
上面的代碼中改變了構(gòu)造函數(shù)的值為一個對象,對象中的屬性 name 并沒有影響實例的 name 屬性值。
實例屬性 __proto__上面訪問實例 p 的原型,實際使用 p.constructor.prototype 去找原型對象,當(dāng)構(gòu)造函數(shù)的值改變后是找不到原型對象的,所以實例并不是通過 constructor.prototype 去查找原型對象的,而是通過每一個實例都有的 __proto__ 屬性,這個屬性指向創(chuàng)建實例的構(gòu)造函數(shù)原本的原型對象,這個屬性不是標(biāo)準(zhǔn),在 IE 下不存在。
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.job = "qianduan"; var p = new Person("nihao", 16); p.__proto__.job; // qianduan
當(dāng)構(gòu)造函數(shù)的 prototype 屬性值被改變之后,在之前創(chuàng)建的實例的 __proto__ 屬性值的仍然引用原型對象,所以對構(gòu)造函數(shù)改變前創(chuàng)建的實例是沒有影響的,會影響后面創(chuàng)建的實例。
原型鏈查找機制實例對象在調(diào)用了一個屬性或方法時,如果對象本身沒有這個屬性或方法,會去自己的原型對象查找,也就是 __proto__ 中查找,如果原型對象中沒有,去原型對象的原型對象查找,一般(原型鏈沒有被修改)情況下就是去 __proto__ 的 __proto__ 中查找,即頂級原型對象 Object.prototype,如果實例對象本身有這個屬性,則直接輸出,不再向上查找,如果對象本身和原型對象具有同名屬性,則會屏蔽掉原型對象的屬性。
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.job = "qianduan"; var p = new Person("nihao", 16); p.job; // qianduan p.job = "houtai"; p.job; // houtai p.__proto__.job; // qianduan總結(jié)
原型鏈的指向及原型鏈的查找機制是 JavaScript 中非常重要的基礎(chǔ)知識,理解原型鏈?zhǔn)歉钊肓私饫^承和面向?qū)ο缶幊痰谋亟?jīng)之路。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/98288.html
摘要:在這其中我們就逃不開要討論繼承原型對象構(gòu)造函數(shù)實例了。想要獲得某一類型的構(gòu)造函數(shù)可以用來獲得,也可以對該屬性進行賦值操作。三上面就提到一點是指構(gòu)造函數(shù)的原型對象,它是一個對象,它是構(gòu)造函數(shù)的屬性。 原型鏈這一個話題,需要和很多概念一起講,才能串成一個比較系統(tǒng)的知識點。在這其中我們就逃不開要討論繼承、原型對象、構(gòu)造函數(shù)、實例了。 一、構(gòu)造函數(shù) 構(gòu)造函數(shù)是一類特殊的函數(shù),它的作用是用來生成...
摘要:在講原型之前,先簡單介紹一下幾個概念構(gòu)造函數(shù)例如上述代碼創(chuàng)建的函數(shù)就被稱為構(gòu)造函數(shù)。同一個構(gòu)造函數(shù)實例化得到的多個對象具有相同的原型對象,所以經(jīng)常使用原型對象來實現(xiàn)繼承。實例對象通過操作構(gòu)造函數(shù)所創(chuàng)建的對象是實例對象。 對于很多前端開發(fā)者而言,JavaScript的原型實在是很讓人頭疼,所以我這邊就整理了一下自己對應(yīng)原型的一點理解,分享給大家,供交流使用 原型 說起原型,那就不得不說p...
摘要:在講原型之前,先簡單介紹一下幾個概念構(gòu)造函數(shù)例如上述代碼創(chuàng)建的函數(shù)就被稱為構(gòu)造函數(shù)。同一個構(gòu)造函數(shù)實例化得到的多個對象具有相同的原型對象,所以經(jīng)常使用原型對象來實現(xiàn)繼承。實例對象通過操作構(gòu)造函數(shù)所創(chuàng)建的對象是實例對象。 對于很多前端開發(fā)者而言,JavaScript的原型實在是很讓人頭疼,所以我這邊就整理了一下自己對應(yīng)原型的一點理解,分享給大家,供交流使用 原型 說起原型,那就不得不說p...
摘要:在中,主要有兩種創(chuàng)建對象的方法分別是對象字面量以及調(diào)用構(gòu)造函數(shù)對象字面量調(diào)用構(gòu)造函數(shù)其實上述兩種創(chuàng)建對象的方法,本質(zhì)上是一樣的,都是引擎調(diào)用對象的構(gòu)造函數(shù)來新建出一個對象。 原型與原型鏈?zhǔn)莏avascript里面最最核心的內(nèi)容,如果不能理解它們之間的存在關(guān)系的話,那么我們是不能理解這門語言的。 在JS中,主要有兩種創(chuàng)建對象的方法, 分別是對象字面量以及調(diào)用構(gòu)造函數(shù) //對象字面量 va...
閱讀 966·2023-04-25 22:13
閱讀 2403·2019-08-30 15:56
閱讀 2288·2019-08-30 11:21
閱讀 714·2019-08-30 11:13
閱讀 2075·2019-08-26 14:06
閱讀 2028·2019-08-26 12:11
閱讀 2351·2019-08-23 16:55
閱讀 596·2019-08-23 15:30