__proto__、prototype傻傻分不清楚? 記住以下兩點:1.__proto__是每個對象都有的一個屬性,而prototype是函數才會有的屬性。2.__proto__指向的是當前對象的原型對象,而prototype指向的,是以當前函數作為構造函數構造出來的對象的原型對象 (寫在最前面,轉 ...
__proto__
、prototype傻傻分不清楚? 記住以下兩點:1.
__proto__
是每個對象都有的一個屬性,而prototype是函數才會有的屬性。2.
__proto__
指向的是當前對象的原型對象,而prototype指向的,是以當前函數作為構造函數構造出來的對象的原型對象
(寫在最前面,轉自知乎@劉狗蛋)
var Person=function(){
this.age=1;
}
Person.prototype.name="wwx";
現在來實例化一個Person
1、var b={};
2、b.__proto__=Person.prototype;
console.log(b)
console.log(b.name)
__proto__
是什麼?我們在這裡簡單地說下。每個對象都會在其內部初始化一個屬性,就是__proto__
,當我們訪問一個對象的屬性 時,如果這個對象內部不存在這個屬性,那麼他就會去__proto__
里找這個屬性,這個__proto__
又會有自己的__proto__
,於是就這樣 一直找下去,也就是我們平時所說的原型鏈的概念。
3、此時我們還需要讓b這個對象有age屬性,這時候我們可以b.age=1; OK加上了
Oh,No!讓我們來想一些東西 如果Person 有100個屬性呢,我們就要100個b.xxx=YYY. 太複雜了,真的不能忍!
Person.call(b) 搞定!此時應該有疑問,為什麼一個call就可以搞定呢?其內部究竟是怎麼實現的?
以上其實也就是相當於 var b = new Person();
這個new究竟做了什麼?我們可以把new的過程拆分成以下三步:其實也就是我們上面那三步
-
var b={}; 也就是說,初始化一個對象b。
-
b.__proto__
=Person.prototype; -
Person.call(b);也就是說構造b,也可以稱之為初始化b。
思考:call 並不能call出來Person.prototype驗證:
var Boy=function (){
this.sex="man";
}
Boy.prototype.hair="black";
var c={};
Boy.call(c)
console.log(c.hair) //undefined
call()的官方解釋,“調用一個對象的一個方法,以另一個對象替換當前對象。”
Person.call(b); 等等Person 好像不符合 “一個對象的一個方法”,其實非也,你可以列印一下 windown.Person
練習:
附上一段官方翻譯:
Each constructor is a function that has a property named “prototype” that is used to implement prototype-based inheritance and shared properties. Every object created by a constructor has an implicit reference (called the object’s prototype) to the value of its constructor’s “prototype” property.
When a constructor creates an object, that object implicitly references the constructor’s prototype property for the purpose of resolving property references. The constructor’s prototype property can be referenced by the program expression constructor.prototype, and properties added to an object’s prototype are shared, through inheritance, by all objects sharing the prototype. Alternatively, a new object may be created with an explicitly specified prototype by using the Object.create built-in function. –ECMAScript® 2015 Language Specification
每個構造函數都有一個名為“prototype”的屬性,用於實現基於原型的繼承和共用屬性。 由構造函數創建的每個對象都有一個隱式引用(稱為對象的原型),以指向其構造函數的“prototype”屬性的值。
當構造函數創建一個對象時,為瞭解析屬性引用,該對象隱式引用構造函數的prototype屬性。 構造函數的prototype屬性可以通過程式表達式constructor.prototype來引用,並且添加到對象原型的屬性通過繼承共用原型的所有對象來共用。 或者,可以使用Object.create內置函數通過顯式指定的原型創建新對象。 -ECMAScript®2015語言規範