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