Javascript原型钩沉
寫(xiě)在前面的總結(jié):
JS當(dāng)中創(chuàng)建一個(gè)對(duì)象有好幾種方式,大體上就是以下幾種:
①通過(guò)var obj ={...}
這種方式一般稱(chēng)為字面量方式,{}直接寫(xiě)需要定義的字段
②var obj = new Object()
Object對(duì)象是JS的內(nèi)建對(duì)象
③通過(guò)構(gòu)造函數(shù)創(chuàng)建對(duì)象
例如:
function father(){ this.name = "I'm your father!" } var f = new father();這里通過(guò)構(gòu)造函數(shù)的方式創(chuàng)建了一個(gè)對(duì)象實(shí)例f
④通過(guò)Object.create創(chuàng)建對(duì)象
Object.create(proto [, propertiesObject ]) 是E5中提出的一種新的對(duì)象創(chuàng)建方式,第一個(gè)參數(shù)是要繼承的原型,如果不是一個(gè)子函數(shù),可以傳一個(gè)null,第二個(gè)參數(shù)是對(duì)象的屬性描述符,這個(gè)參數(shù)是可選的。
?
1.原型是什么?
首先應(yīng)該知道我們創(chuàng)建的每一個(gè)函數(shù)都有一個(gè)prototype屬性,這個(gè)屬性是一個(gè)指向原型對(duì)象的指針,這個(gè)原型對(duì)象的用途是包含由特定類(lèi)型所有實(shí)例共享的屬性和方法。
也就是說(shuō),每創(chuàng)建一個(gè)函數(shù),就會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)的原型對(duì)象。
一個(gè)對(duì)象的真正原型是被對(duì)象內(nèi)部的[[Prototype]]屬性(property)所持有。ECMA引入了標(biāo)準(zhǔn)對(duì)象原型訪問(wèn)器Object.getPrototype(object),到目前為止只有Firefox和chrome實(shí)現(xiàn)了此訪問(wèn)器。除了IE,其他的瀏覽器支持非標(biāo)準(zhǔn)的訪問(wèn)器__proto__,如果這兩者都不起作用的,我們需要從對(duì)象的構(gòu)造函數(shù)中找到的它原型屬性。?
還是挺抽象,舉個(gè)例子吧:
function Person(){this.name="大橙子";this.age = 26;this.sex = "純爺們"; }var p = new Person();console.log(p.name); console.log(p.age); console.log(p.sex); console.log(p.career);Person.prototype.career = "程序員"; console.log(p.career);輸出結(jié)果: [Web瀏覽器] "大橙子" [Web瀏覽器] "26" [Web瀏覽器] "純爺們" [Web瀏覽器] "undefined" [Web瀏覽器] "程序員"上面Person.prototype.career = "程序員";就是通過(guò)原型來(lái)添加的屬性,所有繼承這個(gè)Person的對(duì)象,都具有career這個(gè)屬性。
這個(gè)過(guò)程是這樣的,當(dāng)輸出p.career的時(shí)候,首先會(huì)在對(duì)象p找,因?yàn)?span lang="en-us">p對(duì)象沒(méi)有career這個(gè)屬性,這就是為什么會(huì)輸出undefined的原因,然后繼續(xù)向上查找,在Person.prototype中找到了career,然后就輸出了“程序員”。?
要了解原型的概念,應(yīng)該知道_proto_、prototype以及constructor他們之間是什么聯(lián)系
那么就來(lái)分析一下var p = new Person(); 這個(gè)過(guò)程
上面這個(gè)分析圖可以很好的展示,三者的關(guān)系,
首先要知道幾個(gè)地方,
第一點(diǎn):就是Empty()函數(shù),這個(gè)函數(shù)是所有函數(shù)的原型,并且他很特殊沒(méi)有prototype
第二點(diǎn):__proto__是內(nèi)部原型,prototype是構(gòu)造器原型(構(gòu)造器其實(shí)就是函數(shù),所以上面才說(shuō)這個(gè)是函數(shù)對(duì)象才有的,而_proto_是每個(gè)對(duì)象都有的。我的理解它才是構(gòu)成原型鏈的原因)
①.從中間開(kāi)始看,首先我創(chuàng)建了一個(gè)函數(shù)person(),同時(shí)JS幫我創(chuàng)建了一個(gè)原型對(duì)象person.prototype
并把我的person()的prototype指針指向了它,原型對(duì)象中有一個(gè)constructor屬性,指向了我的person()函數(shù)。
②.當(dāng)我new一個(gè)person實(shí)例的時(shí)候,新創(chuàng)建的實(shí)例對(duì)象p的_proto_指向了person.prototype
這也是為什么,我在person.prototype中添加屬性,p也能反映出來(lái)的根本原因。
③.person.prototype也是一個(gè)對(duì)象,那么他的_proto_是誰(shuí)呢,如上圖就是Object.prototype,這也不難理解,因?yàn)?span lang="en-us">Object是Javascript中所有對(duì)象的父級(jí)對(duì)象,我們創(chuàng)建的所有對(duì)象都繼承于此,包括內(nèi)建對(duì)象。同樣因?yàn)樗彩菍?duì)象,那么它也擁有_proto_,圖上表示了它的原型就是null
我們可以打印每一屬性的值來(lái)進(jìn)行確認(rèn):
//Person函數(shù)的原型對(duì)象 console.log(Person.prototype); //Person原型對(duì)象的Constructor console.log(Person.prototype.constructor); //判斷實(shí)例對(duì)象p的原型,是不是Person.prototype console.log(p.__proto__ === Person.prototype?true:false); //函數(shù)對(duì)象Person的_proto_,是不是Empty() console.log(Person.__proto__); //Empty()是不是沒(méi)有prototype console.log(Person.__proto__.prototype); //Empty()的__proto__是不是Object.prototype console.log(Person.__proto__.__proto__ === Object.prototype?true:false); //Person.prototype的_proto_是不是Object.prototype console.log(Person.prototype.__proto__ === Object.prototype?true:false); //Object.prototype的_proto_是不是null console.log(Object.prototype.__proto__);輸出結(jié)果: [Web瀏覽器] "[object Object]" [Web瀏覽器] "function Person(){this.name="大橙子";this.age = 26;this.sex = "純爺們"; }" [Web瀏覽器] "true" [Web瀏覽器] "function Empty() {}" [Web瀏覽器] "undefined" [Web瀏覽器] "true" [Web瀏覽器] "true" [Web瀏覽器] "null"?
2.原型鏈
上面的原型我們舉的例子沒(méi)有特別明顯的顯示這個(gè)鏈的過(guò)程,看不到具體的繼承關(guān)系,所以再分析一個(gè)例子
Object.prototype.dead = true;function animal(){} animal.prototype.eat=true; animal.prototype.sleep=true;function bird(){this.fly = true; }bird.prototype = new animal(); var a = new animal(); var b = new bird();console.log(a.fly); console.log(a.eat); console.log(a.sleep); console.log(a.dead); console.log(b.fly); console.log(b.eat); console.log(b.sleep); console.log(b.dead);測(cè)試輸出: [Web瀏覽器] "undefined" [Web瀏覽器] "true" [Web瀏覽器] "true" [Web瀏覽器] "true" [Web瀏覽器] "true" [Web瀏覽器] "true" [Web瀏覽器] "true" [Web瀏覽器] "true"下面我再畫(huà)圖分析一下這個(gè)
①下圖是在bird.prototype = new animal();之前,創(chuàng)建好函數(shù)之后的狀態(tài)
?
②繼續(xù)執(zhí)行程序
從上圖就可以明顯看到
實(shí)例對(duì)象b->bird.prototype->animal.prototype->Object.prototype->null有一個(gè)鏈?zhǔn)降睦^承關(guān)系
也就是為什么
console.log(b.eat);
console.log(b.sleep);
console.log(b.dead);
會(huì)打印出來(lái)true的原因了。
?
轉(zhuǎn)載于:https://www.cnblogs.com/dcz2015/p/5391971.html
總結(jié)
以上是生活随笔為你收集整理的Javascript原型钩沉的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 因kuaipan等PPA造成的Dupli
- 下一篇: 打素数表