成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

__proto__和prototype之區(qū)別和聯(lián)系

paulli3 / 1709人閱讀

摘要:當(dāng)這步完成,這個(gè)對(duì)象就與構(gòu)造函數(shù)再無(wú)聯(lián)系,這個(gè)時(shí)候即使構(gòu)造函數(shù)再加任何成員,都不再影響已經(jīng)實(shí)例化的對(duì)象了。此時(shí),對(duì)象具有了和屬性,同時(shí)具有了構(gòu)造函數(shù)的原型對(duì)象的所有成員,當(dāng)然,此時(shí)該原型對(duì)象是沒有成員的。

學(xué)到原型的時(shí)候感覺頭都大了/(ㄒoㄒ)/~~ 尤其是prototype和__proto__ 傻傻分不清,通過多番查找資料,根據(jù)自己的理解,記錄下最近研究對(duì)象的一些心得,做一個(gè)記錄與總結(jié),以加深自己的印象,同時(shí),希望也能給其他學(xué)JavaScript同胞一點(diǎn)啟發(fā)。

在JavaScript中,萬(wàn)物皆對(duì)象。咱們寫一個(gè)JavaScript對(duì)象,大多數(shù)時(shí)候是用構(gòu)造函數(shù)創(chuàng)建一個(gè)對(duì)象或者用對(duì)象字面量創(chuàng)建一個(gè)對(duì)象。比如:

//通過構(gòu)造函數(shù)來創(chuàng)建對(duì)象
function Person() {
    //...
}
var person1 = new Person();
//通過對(duì)象字面量創(chuàng)建對(duì)象
var person2 = {
    name: "jessica",
    age: 27,
    job: "teacher"
}

當(dāng)然還有其他方式創(chuàng)建對(duì)象,這里就不列舉出來了。那么問題來了,通過不同的方式創(chuàng)建的對(duì)象有什么區(qū)別呢?
我們知道,每個(gè)JS對(duì)象一定對(duì)應(yīng)一個(gè)原型對(duì)象,并從原型對(duì)象繼承屬性和方法。那么對(duì)象是怎么和這個(gè)原型對(duì)象對(duì)應(yīng)的呢?帶著問題慢慢看下面的內(nèi)容吧

__proto__和prototype概念區(qū)分

其實(shí)說__proto__并不準(zhǔn)確,確切的說是對(duì)象的[[prototype]]屬性,只不過在主流的瀏覽器中,都用__proto__來代表[[prototype]]屬性,因?yàn)閇[prototype]]只是一個(gè)標(biāo)準(zhǔn),而針對(duì)這個(gè)標(biāo)準(zhǔn),不同的瀏覽器有不同的實(shí)現(xiàn)方式。在ES5中用Object.getPrototypeOf函數(shù)獲得一個(gè)對(duì)象的[[prototype]]。ES6中,使用Object.setPrototypeOf可以直接修改一個(gè)對(duì)象的[[prototype]]。為了方便,我下面的文章用__proto__來代表對(duì)象的[[prototype]]。

而prototype屬性是只有函數(shù)才特有的屬性,當(dāng)你創(chuàng)建一個(gè)函數(shù)時(shí),js會(huì)自動(dòng)為這個(gè)函數(shù)加上prototype屬性,值是一個(gè)空對(duì)象。所以,函數(shù)在js中是非常特殊的,是所謂的一等公民。
那么__proto__和prototype是怎么聯(lián)系起來的呢?讓我們來看下下面的代碼:

function Person(name, age) {
    this.name = name;
    this.age = age;
}
var person1 = new Person("jessica", 27);

當(dāng)我們new Person()的時(shí)候到底發(fā)生了什么?
new一個(gè)構(gòu)造函數(shù),相當(dāng)于實(shí)例化一個(gè)對(duì)象,這期間其實(shí)進(jìn)行了這三個(gè)步驟:

創(chuàng)建對(duì)象,設(shè)為o,即:?var o = {};
上文提到了,每個(gè)對(duì)象都有__proto__屬性,該屬性指向一個(gè)對(duì)象,這里,將o對(duì)象的__Proto__指向構(gòu)造函數(shù)Person的原型對(duì)象(Person.prototype);
將o作為this去調(diào)用構(gòu)造函數(shù)Person,從而設(shè)置o的屬性和方法并初始化。
當(dāng)這3步完成,這個(gè)o對(duì)象就與構(gòu)造函數(shù)Person再無(wú)聯(lián)系,這個(gè)時(shí)候即使構(gòu)造函數(shù)Person再加任何成員,都不再影響已經(jīng)實(shí)例化的o對(duì)象了。
此時(shí),o對(duì)象具有了name和age屬性,同時(shí)具有了構(gòu)造函數(shù)Person的原型對(duì)象的所有成員,當(dāng)然,此時(shí)該原型對(duì)象是沒有成員的。

現(xiàn)在大家都明白了吧,簡(jiǎn)單的總結(jié)下就是:
js在創(chuàng)建對(duì)象的時(shí)候,都有一個(gè)叫做__proto__的內(nèi)置屬性,用于指向創(chuàng)建它的函數(shù)對(duì)象的原型對(duì)象prototype
那么一個(gè)對(duì)象的__proto__屬性究竟怎么決定呢?答案顯而易見了:是由構(gòu)造該對(duì)象的方法決定的。

創(chuàng)建對(duì)象的不同方法解析

下面講解三種常見的創(chuàng)建對(duì)象方法。

對(duì)象字面量

比如:

var Person = {
    name: "jessica",
    age: 27
}

這種形式就是對(duì)象字面量,通過對(duì)象字面量構(gòu)造出的對(duì)象,其__proto__指向Object.prototype。
所以,其實(shí)Object是一個(gè)函數(shù)也不難理解了。Object、Function都是是js自帶的函數(shù)對(duì)象。
可以跑下面的代碼看看:

console.log(typeof Object); 
console.log(typeof Function);
構(gòu)造函數(shù)

就如我前面講的,形如:

function Person(){}
var person1 = new Person();

這種形式創(chuàng)建對(duì)象的方式就是通過構(gòu)造函數(shù)創(chuàng)建對(duì)象,這里的構(gòu)造函數(shù)是Person函數(shù)。上面也講過了,通過構(gòu)造函數(shù)創(chuàng)建的對(duì)象,其__proto指向的是構(gòu)造函數(shù)的prototype屬性指向的對(duì)象。

Object.create
var person1 = {
    name: "jessica",
    age: 27
}
var person2 = Object.create(person1);

這種情況下,person2的__proto__指向person1。在沒有Object.create函數(shù)的時(shí)候,人們大多是這樣做的:

Object.create = function(p) {
    function f(){};
    f.prototype = p;
    return new f();
}

一看大家就會(huì)明白了。

總結(jié)

其實(shí)仔細(xì)思考下上面提到的三種創(chuàng)建對(duì)象的方法,追究其本質(zhì),不難發(fā)現(xiàn),最根本的還是利用構(gòu)造函數(shù)再通過new來創(chuàng)建對(duì)象。所謂的對(duì)象字面量也只不過是語(yǔ)法糖而已,本質(zhì)上是var o = new Object(); o.xx = xx;o.yy=yy;。 所以,函數(shù)真不愧是js中的一等公民呀~

原型鏈

既然已經(jīng)提到了原型,就不得不提一下原型鏈了,畢竟這是實(shí)現(xiàn)繼承最關(guān)鍵所在,也是js對(duì)象精妙所在。
還記得上文提到的一個(gè)總結(jié)嗎?不記得?沒關(guān)系,我貼出來讓大家溫故而知新,哈哈~
js在創(chuàng)建對(duì)象的時(shí)候,都有一個(gè)叫做__proto__的內(nèi)置屬性,用于指向創(chuàng)建它的函數(shù)對(duì)象的原型對(duì)象prototype
而原型鏈的基本思想就是利用原型讓一個(gè)引用類型繼承另一個(gè)引用類型的屬性和方法。
讓我們?cè)俸?jiǎn)單回顧下構(gòu)造函數(shù)、原型和實(shí)例的關(guān)系:
每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象包含一個(gè)指向構(gòu)造函數(shù)的指針(constructor),而實(shí)例則包含一個(gè)指向原型對(duì)象的內(nèi)部指針(__proto__)。
我們拿一個(gè)例子來講解:

function Person(name, age) {
    this.name = name;
    this.age = age;
}
var person1 = new Person("jessica", 27);

一圖勝前言,我們用畫圖的形式來講解下上面的例子:

從上圖可以看到,其實(shí)原型鏈的頂端是Object.prototype.__proto__,也即為null。

總結(jié)

函數(shù)是js中的一等公民,js在創(chuàng)建對(duì)象的時(shí)候,都有一個(gè)叫做__proto__的內(nèi)置屬性,用于指向創(chuàng)建它的函數(shù)對(duì)象的原型對(duì)象prototype。只有函數(shù)有prototype, 當(dāng)你創(chuàng)建一個(gè)函數(shù)時(shí),js會(huì)自動(dòng)為這個(gè)函數(shù)加上prototype屬性,值是一個(gè)空對(duì)象。

祝大家早日富可敵國(guó),bye~

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97677.html

相關(guān)文章

  • javascript對(duì)象詳解:__proto__prototype的區(qū)別聯(lián)系

    摘要:當(dāng)這步完成,這個(gè)對(duì)象就與構(gòu)造函數(shù)再無(wú)聯(lián)系,這個(gè)時(shí)候即使構(gòu)造函數(shù)再加任何成員,都不再影響已經(jīng)實(shí)例化的對(duì)象了。此時(shí),對(duì)象具有了和屬性,同時(shí)具有了構(gòu)造函數(shù)的原型對(duì)象的所有成員,當(dāng)然,此時(shí)該原型對(duì)象是沒有成員的。 前言 本篇文章用來記錄下最近研究對(duì)象的一些心得,做一個(gè)記錄與總結(jié),以加深自己的印象,同時(shí),希望也能給正在學(xué)習(xí)中的你一點(diǎn)啟發(fā)。本文適合有一定JavaScript基礎(chǔ)的童鞋閱讀。原文戳這...

    chavesgu 評(píng)論0 收藏0
  • 關(guān)于javascript的原型原型鏈,看我就夠了(二)

    摘要:原文鏈接關(guān)于的原型和原型鏈,看我就夠了一參考鏈接闖關(guān)記之原型及原型鏈之原型與原型鏈一篇文章帶你理解原型和原型鏈徹底理解原型鏈一的默認(rèn)指向圖解和的三角關(guān)系原型和原型鏈三張圖搞懂的原型對(duì)象與原型鏈 溫故 創(chuàng)建對(duì)象的三種方式 通過對(duì)象直接量 通過new創(chuàng)建對(duì)象 通過Object.create() js中對(duì)象分為兩種 函數(shù)對(duì)象 普通對(duì)象 仔細(xì)觀察如下代碼 function Foo(na...

    eccozhou 評(píng)論0 收藏0
  • 深入學(xué)習(xí)js——原型原型鏈

    摘要:我們用一張圖表示構(gòu)造函數(shù)和實(shí)例原型之間的關(guān)系好了構(gòu)造函數(shù)和實(shí)例原型之間的關(guān)系我們已經(jīng)梳理清楚了,那我們?cè)趺幢硎緦?shí)例與實(shí)例原型,也就是或者和之間的關(guān)系呢。 開篇: 在Brendan Eich大神為JavaScript設(shè)計(jì)面向?qū)ο笙到y(tǒng)的時(shí)候,借鑒了Self 和Smalltalk這兩門基于原型的語(yǔ)言,之所以選擇基于原型的面向?qū)ο笙到y(tǒng),并不是因?yàn)闀r(shí)間匆忙,它設(shè)計(jì)起來相對(duì)簡(jiǎn)單,而是因?yàn)閺囊婚_始B...

    FingerLiu 評(píng)論0 收藏0
  • 深入學(xué)習(xí)js——原型原型鏈

    摘要:我們用一張圖表示構(gòu)造函數(shù)和實(shí)例原型之間的關(guān)系好了構(gòu)造函數(shù)和實(shí)例原型之間的關(guān)系我們已經(jīng)梳理清楚了,那我們?cè)趺幢硎緦?shí)例與實(shí)例原型,也就是或者和之間的關(guān)系呢。 開篇: 在Brendan Eich大神為JavaScript設(shè)計(jì)面向?qū)ο笙到y(tǒng)的時(shí)候,借鑒了Self 和Smalltalk這兩門基于原型的語(yǔ)言,之所以選擇基于原型的面向?qū)ο笙到y(tǒng),并不是因?yàn)闀r(shí)間匆忙,它設(shè)計(jì)起來相對(duì)簡(jiǎn)單,而是因?yàn)閺囊婚_始B...

    xialong 評(píng)論0 收藏0
  • 淺析JavaScript中原型及constructor、__proto__、prototype的關(guān)系

    摘要:搞清了構(gòu)造函數(shù)和原型的區(qū)別后,就可以繼續(xù)了。指向構(gòu)造函數(shù)的原型對(duì)象,存在于實(shí)例與構(gòu)造函數(shù)的原型對(duì)象之間。要注意的是當(dāng)我們使用下面這種將整個(gè)重寫的情況時(shí),會(huì)切斷構(gòu)造函數(shù)和原型之間的聯(lián)系,也就是說不再指向了,而是指向。 前言 先說一說為什么要搞清楚JavaScript的原型,因?yàn)檫@就是JS的根。JavaScript雖然不是一門傳統(tǒng)的面向?qū)ο笳Z(yǔ)言,但它有自己的類和繼承機(jī)制,最重要的就是它采用...

    wenzi 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<