摘要:當(dāng)這步完成,這個對象就與構(gòu)造函數(shù)再無聯(lián)系,這個時候即使構(gòu)造函數(shù)再加任何成員,都不再影響已經(jīng)實例化的對象了。此時,對象具有了和屬性,同時具有了構(gòu)造函數(shù)的原型對象的所有成員,當(dāng)然,此時該原型對象是沒有成員的。
前言
本篇文章用來記錄下最近研究對象的一些心得,做一個記錄與總結(jié),以加深自己的印象,同時,希望也能給正在學(xué)習(xí)中的你一點啟發(fā)。本文適合有一定JavaScript基礎(chǔ)的童鞋閱讀。原文戳這里
引言在JavaScript中,萬物皆對象。咱們寫一個JavaScript對象,大多數(shù)時候是用構(gòu)造函數(shù)創(chuàng)建一個對象或者用對象字面量創(chuàng)建一個對象。比如:
//通過構(gòu)造函數(shù)來創(chuàng)建對象 function Person() { //... } var person1 = new Person(); //通過對象字面量創(chuàng)建對象 var person2 = { name: "jessica", age: 27, job: "teacher" }
當(dāng)然還有其他方式創(chuàng)建對象,這里就不列舉出來了。那么問題來了,通過不同的方式創(chuàng)建的對象有什么區(qū)別呢?
我們知道,每個JS對象一定對應(yīng)一個原型對象,并從原型對象繼承屬性和方法。那么對象是怎么和這個原型對象對應(yīng)的呢?帶著問題慢慢看下面的內(nèi)容吧~
__proto__和prototype概念區(qū)分其實說__proto__并不準(zhǔn)確,確切的說是對象的[[prototype]]屬性,只不過在主流的瀏覽器中,都用__proto__來代表[[prototype]]屬性,因為[[prototype]]只是一個標(biāo)準(zhǔn),而針對這個標(biāo)準(zhǔn),不同的瀏覽器有不同的實現(xiàn)方式。在ES5中用Object.getPrototypeOf函數(shù)獲得一個對象的[[prototype]]。ES6中,使用Object.setPrototypeOf可以直接修改一個對象的[[prototype]]。為了方便,我下面的文章用__proto__來代表對象的[[prototype]]。
而prototype屬性是只有函數(shù)才特有的屬性,當(dāng)你創(chuàng)建一個函數(shù)時,js會自動為這個函數(shù)加上prototype屬性,值是一個空對象。所以,函數(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()的時候到底發(fā)生了什么?
new一個構(gòu)造函數(shù),相當(dāng)于實例化一個對象,這期間其實進行了這三個步驟:
創(chuàng)建對象,設(shè)為o,即: var o = {};
上文提到了,每個對象都有__proto__屬性,該屬性指向一個對象,這里,將o對象的__Proto__指向構(gòu)造函數(shù)Person的原型對象(Person.prototype);
將o作為this去調(diào)用構(gòu)造函數(shù)Person,從而設(shè)置o的屬性和方法并初始化。
當(dāng)這3步完成,這個o對象就與構(gòu)造函數(shù)Person再無聯(lián)系,這個時候即使構(gòu)造函數(shù)Person再加任何成員,都不再影響已經(jīng)實例化的o對象了。
此時,o對象具有了name和age屬性,同時具有了構(gòu)造函數(shù)Person的原型對象的所有成員,當(dāng)然,此時該原型對象是沒有成員的。
現(xiàn)在大家都明白了吧,簡單的總結(jié)下就是:
js在創(chuàng)建對象的時候,都有一個叫做__proto__的內(nèi)置屬性,用于指向創(chuàng)建它的函數(shù)對象的原型對象prototype
那么一個對象的__proto__屬性究竟怎么決定呢?答案顯而易見了:是由構(gòu)造該對象的方法決定的。
創(chuàng)建對象的不同方法解析下面講解三種常見的創(chuàng)建對象方法。
對象字面量比如:
var Person = { name: "jessica", age: 27 }
這種形式就是對象字面量,通過對象字面量構(gòu)造出的對象,其__proto__指向Object.prototype。
所以,其實Object是一個函數(shù)也不難理解了。Object、Function都是是js自帶的函數(shù)對象。
可以跑下面的代碼看看:
console.log(typeof Object); console.log(typeof Function);構(gòu)造函數(shù)
就如我前面講的,形如:
function Person(){} var person1 = new Person();
這種形式創(chuàng)建對象的方式就是通過構(gòu)造函數(shù)創(chuàng)建對象,這里的構(gòu)造函數(shù)是Person函數(shù)。上面也講過了,通過構(gòu)造函數(shù)創(chuàng)建的對象,其__proto指向的是構(gòu)造函數(shù)的prototype屬性指向的對象。
Object.createvar person1 = { name: "jessica", age: 27 } var person2 = Object.create(person1);
這種情況下,person2的__proto__指向person1。在沒有Object.create函數(shù)的時候,人們大多是這樣做的:
Object.create = function(p) { function f(){}; f.prototype = p; return new f(); }
一看大家就會明白了。
總結(jié)其實仔細思考下上面提到的三種創(chuàng)建對象的方法,追究其本質(zhì),不難發(fā)現(xiàn),最根本的還是利用構(gòu)造函數(shù)再通過new來創(chuàng)建對象。所謂的對象字面量也只不過是語法糖而已,本質(zhì)上是var o = new Object(); o.xx = xx;o.yy=yy;。 所以,函數(shù)真不愧是js中的一等公民呀~
原型鏈既然已經(jīng)提到了原型,就不得不提一下原型鏈了,畢竟這是實現(xiàn)繼承最關(guān)鍵所在,也是js對象精妙所在。
還記得上文提到的一個總結(jié)嗎?不記得?沒關(guān)系,我貼出來讓大家溫故而知新,哈哈~
js在創(chuàng)建對象的時候,都有一個叫做__proto__的內(nèi)置屬性,用于指向創(chuàng)建它的函數(shù)對象的原型對象prototype
而原型鏈的基本思想就是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。
讓我們再簡單回顧下構(gòu)造函數(shù)、原型和實例的關(guān)系:
每個構(gòu)造函數(shù)都有一個原型對象,原型對象包含一個指向構(gòu)造函數(shù)的指針(constructor),而實例則包含一個指向原型對象的內(nèi)部指針(__proto__)。
我們拿一個例子來講解:
function Person(name, age) { this.name = name; this.age = age; } var person1 = new Person("jessica", 27);
一圖勝前言,我們用畫圖的形式來講解下上面的例子:
從上圖可以看到,其實原型鏈的頂端是Object.prototype.__proto__,也即為null。
總結(jié)函數(shù)是js中的一等公民,js在創(chuàng)建對象的時候,都有一個叫做__proto__的內(nèi)置屬性,用于指向創(chuàng)建它的函數(shù)對象的原型對象prototype。只有函數(shù)有prototype, 當(dāng)你創(chuàng)建一個函數(shù)時,js會自動為這個函數(shù)加上prototype屬性,值是一個空對象。
參考文獻js 對象、原型、繼承詳解
js中__proto__和prototype的區(qū)別和關(guān)系?
理解JavaScript原型
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/86999.html
摘要:當(dāng)這步完成,這個對象就與構(gòu)造函數(shù)再無聯(lián)系,這個時候即使構(gòu)造函數(shù)再加任何成員,都不再影響已經(jīng)實例化的對象了。此時,對象具有了和屬性,同時具有了構(gòu)造函數(shù)的原型對象的所有成員,當(dāng)然,此時該原型對象是沒有成員的。 學(xué)到原型的時候感覺頭都大了/(ㄒoㄒ)/~~ 尤其是prototype和__proto__ 傻傻分不清,通過多番查找資料,根據(jù)自己的理解,記錄下最近研究對象的一些心得,做一個記錄與總...
摘要:原型對象內(nèi)部也有一個指針屬性指向構(gòu)造函數(shù)實例可以訪問原型對象上定義的屬性和方法。在創(chuàng)建子類型的實例時,不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù)。 贊助我以寫出更好的文章,give me a cup of coffee? 2017最新最全前端面試題 私有變量和函數(shù) 在函數(shù)內(nèi)部定義的變量和函數(shù),如果不對外提供接口,外部是無法訪問到的,也就是該函數(shù)的私有的變量和函數(shù)。 function ...
摘要:對象詳解對象深度剖析,深度理解對象這算是醞釀很久的一篇文章了。用空構(gòu)造函數(shù)設(shè)置類名每個對象都共享相同屬性每個對象共享一個方法版本,省內(nèi)存。 js對象詳解(JavaScript對象深度剖析,深度理解js對象) 這算是醞釀很久的一篇文章了。 JavaScript作為一個基于對象(沒有類的概念)的語言,從入門到精通到放棄一直會被對象這個問題圍繞。 平時發(fā)的文章基本都是開發(fā)中遇到的問題和對...
摘要:二構(gòu)造函數(shù)我們先復(fù)習(xí)一下構(gòu)造函數(shù)的知識上面的例子中和都是的實例。這兩個實例都有一個構(gòu)造函數(shù)屬性,該屬性是一個指針指向。原型鏈其中是對象的實例。 一. 普通對象與函數(shù)對象 JavaScript 中,萬物皆對象!但對象也是有區(qū)別的。分為普通對象和函數(shù)對象,Object 、Function 是 JS 自帶的函數(shù)對象。下面舉例說明 var o1 = {}; var o2 =new Objec...
摘要:而和的存在就是為了建立這種子類與父類間的聯(lián)系。創(chuàng)建一個基本對象建立新對象與原型我把它理解為類之間的連接執(zhí)行構(gòu)造函數(shù)小結(jié)可以理解為類,也就是存儲一類事物的基本信息。原型原型鏈和繼承之間的關(guān)系。 原型 原型的背景 首先,你應(yīng)該知道javascript是一門面向?qū)ο笳Z言。 是對象,就具有繼承性。 繼承性,就是子類自動共享父類的數(shù)據(jù)結(jié)構(gòu)和方法機制。 而prototype 和 __proto__...
閱讀 711·2021-11-22 13:54
閱讀 3077·2021-09-26 10:16
閱讀 3502·2021-09-08 09:35
閱讀 1585·2019-08-30 15:55
閱讀 3434·2019-08-30 15:54
閱讀 2082·2019-08-30 10:57
閱讀 502·2019-08-29 16:25
閱讀 882·2019-08-29 16:15