Javascript中prototype與__proto__的關(guān)系詳解
前言
學(xué)到原型的時候感覺頭都大了/(ㄒoㄒ)/~~ 尤其是prototype和__proto__ 傻傻分不清 通過多番查找資料,根據(jù)自己的理解,總結(jié)如下:
一、構(gòu)造函數(shù):
構(gòu)造函數(shù):通過new關(guān)鍵字可以用來創(chuàng)建特定類型的對象的函數(shù)。比如像Object和Array,兩者屬于內(nèi)置的原生的構(gòu)造函數(shù),在運(yùn)行時會自動的出現(xiàn)在執(zhí)行環(huán)境中,可以直接使用。如下:
var arr = new Array();//使用Array構(gòu)造函數(shù)創(chuàng)建了一個array實(shí)例arr arr[0]="a"; arr[1]="b"; alert(arr);//a,b var obj=new Object();//使用Object構(gòu)造函數(shù)創(chuàng)建了一個Object實(shí)例obj obj.name="c"; obj.age=12; alert(obj.name);//c
我們可以自定義的創(chuàng)建構(gòu)造函數(shù),并為其自定義屬性和方法,如:
//創(chuàng)建構(gòu)造函數(shù)Person function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ alert(this.name)// }; } //使用new關(guān)鍵字,來生成Person實(shí)例 var person1=new Person("Tom",22); var person2=new Person("Jerry",21); person1.sayName();//Tom person2.sayName();//Jerry
注意以下幾點(diǎn):
- 構(gòu)造函數(shù)的名字始終要以大寫字母開頭(主要是為了區(qū)別于非構(gòu)造函數(shù),也即是區(qū)別于普通函數(shù))
- 構(gòu)造函數(shù)也就是函數(shù),定義構(gòu)造函數(shù)和定義普通函數(shù)的語法一樣。構(gòu)造函數(shù)和普通函數(shù)的區(qū)別在于:使用他們的方式不同。任何函數(shù)只要使用new操作符來調(diào)用,那他就可以作為構(gòu)造函數(shù);不使用new操作符來調(diào)用就是普通函數(shù)
function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ alert(this.name)// }; } //當(dāng)做構(gòu)造函數(shù)使用 var person=new Person("Tom",22); person.sayName();//Tom //當(dāng)做普通函數(shù)使用 Person("Jerry",30);//添加到window sayName();//Jerry 等同于window.sayName();
二、原型對象:
每個函數(shù)都有一個prototype屬性,它是一個指向原型對象的指針,原型對象在定義函數(shù)時同時被創(chuàng)建,原型對象的用途是包含所有實(shí)例共享的屬性和方法
function Person(){ } //自定義原型對象的屬性和方法 Person.prototype.name="Tom"; Person.prototype.age=25; Person.prototype.sayName=function(){ alert(this.name); }; //原型對象中的所有屬性和方法 都會自動被所有實(shí)例所共享 var person1=new Person(); var person2=new Person(); person1.sayName();//Tom person2.sayName();//Tom
只要創(chuàng)建了一個新函數(shù),每個函數(shù)在創(chuàng)建之后都會獲得一個prototype的屬性,這個屬性指向函數(shù)的原型對象(原型對象在定義函數(shù)時同時被創(chuàng)建),此原型對象又有一個名為“constructor”的屬性,反過來指向函數(shù)本身,達(dá)到一種循環(huán)指向,
如在上邊的例子中:alert(Person.prototype.constructor===Person);//會返回true
function Person(){} alert(Person.prototype.constructor===Person);//true
三、__proto__(注意這里proto左右兩邊都有兩個"_")
當(dāng)調(diào)用構(gòu)造函數(shù)創(chuàng)建一個新實(shí)例后,該實(shí)例的內(nèi)部將包含一個指針[[Prototype]],該指針指向創(chuàng)建它的構(gòu)造函數(shù)的原型,在腳本上沒有標(biāo)準(zhǔn)的方法來訪問[[Prototype]],但大多數(shù)瀏覽器都支持通過__proto__來訪問。
function Person(){ } //自定義原型對象的屬性和方法 Person.prototype.name="Tom"; Person.prototype.age=25; Person.prototype.sayName=function(){ alert(this.name); }; //原型對象中的所有屬性和方法 都會自動被所有實(shí)例所共享 var person1=new Person(); var person2=new Person(); person1.sayName();//Tom person2.sayName();//Tom alert(person1.__proto__===Person.prototype);//true
以上述的示例代碼為例,各個對象之間的關(guān)系如下圖所示:
總結(jié):
①只要創(chuàng)建了一個函數(shù),該函數(shù)的原型對象也隨之同時被創(chuàng)建出來,原型對象中的屬性和方法被經(jīng)由其相對應(yīng)的構(gòu)造函數(shù)所創(chuàng)建的實(shí)例所共享
②每個函數(shù)在創(chuàng)建之后都會獲得一個prototype的屬性,這個屬性指向該函數(shù)的原型對象
③每個對象的__proto__屬性都指向其構(gòu)造函數(shù)的原型
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
JS+CSS實(shí)現(xiàn)精美的二級導(dǎo)航效果代碼
這篇文章主要介紹了JS+CSS實(shí)現(xiàn)精美的二級導(dǎo)航效果代碼,涉及JavaScript基于鼠標(biāo)事件動態(tài)變換元素樣式的技巧,非常簡單實(shí)用,需要的朋友可以參考下2015-09-09JS簡單實(shí)現(xiàn)查看文檔創(chuàng)建日期、修改日期和文檔大小的方法示例
這篇文章主要介紹了JS簡單實(shí)現(xiàn)查看文檔創(chuàng)建日期、修改日期和文檔大小的方法,結(jié)合實(shí)例形式分析了JavaScript使用fileCreatedDate屬性、fileModifiedDate屬性、lastModified屬性和fileSize屬性相關(guān)操作技巧,需要的朋友可以參考下2018-04-04純js實(shí)現(xiàn)頁面返回頂部的動畫(超簡單)
下面小編就為大家?guī)硪黄僯s實(shí)現(xiàn)頁面返回頂部的動畫(超簡單)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08javascript中的數(shù)字與字符串相加實(shí)例分析
javascript中的數(shù)字與字符串相加實(shí)例分析,學(xué)習(xí)js的朋友可以參考下。2011-08-08javascript canvas實(shí)現(xiàn)簡易時鐘例子
這篇文章主要為大家詳細(xì)介紹了javascript canvas實(shí)現(xiàn)簡易時鐘例子,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-09-09Javascript 5種方法實(shí)現(xiàn)過濾刪除前后所有空格
這篇文章主要介紹Javascript 5種過濾刪除前后所有空格的方法,比較實(shí)用,需要的朋友可以參考下。2016-06-06javaScript 計(jì)算兩個日期的天數(shù)相差(示例代碼)
本篇文章主要介紹了javaScript 計(jì)算兩個日期的天數(shù)相差(示例代碼) 需要的朋友可以過來參考下,希望對大家有所幫助2013-12-12