萬(wàn)能的例子
function Rectangle(x,y){
this.x = x;
this.y = y;
}
Rectangle.prototype.perimeter=function(){
return 2*(this.x+this.y);
}
var rectangle = new Rectangle();
一個(gè)對(duì)象的原型與對(duì)象的 prototype屬性不是一回事
前者用于在原型鏈中匹配不存在的屬性踪央。后者用于通過(guò) new 關(guān)鍵字創(chuàng)建對(duì)象蕴茴,它將作為新創(chuàng)建對(duì)象的原型爆价。
以最初的例子為例尿褪,rectangle的原型是Rectangle.prototype光绕。轉(zhuǎn)換成代碼就是下面這句話。
// DEPRECATED. This is for example purposes only. DO NOT DO THIS in real code.
//如果確實(shí)需要募狂,請(qǐng)用Object.getPrototypeOf(rectangle)代替rectangle.__proto__
rectangle.__proto__ = Rectangle.prototype;
new 操作符到底做了什么办素?
When the code new Foo(...) is executed, the following things happen:
- A new object is created, inheriting from Foo.prototype.(
inheriting
我的理解是新對(duì)象的原型角雷,即proto,也即Object.getPrototypeOf(新對(duì)象)性穿,指向Foo.prototype,j) - The constructor function Foo is called with the specified arguments, and with this bound to the newly created object. new Foo is equivalent to new Foo(), i.e. if no argument list is specified, Foo is called without arguments.
- The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)
比如當(dāng)你執(zhí)行
var o = new Foo();
var o = new Object();//創(chuàng)建一個(gè)新對(duì)象
o.__proto__ = Foo.prototype;//新對(duì)象的原型執(zhí)行構(gòu)造函數(shù)的prototype屬性
var ret = Foo.call(o);//執(zhí)行構(gòu)造函數(shù)勺三,并將this綁定為新創(chuàng)建的對(duì)象。
if(typeof Foo()==="object"){//如果返回值是一個(gè)對(duì)象
o=Foo();//返回值將覆蓋o
}
為什么實(shí)例的屬性不寫在原型鏈上需曾,而寫在this.xxx里面吗坚,而方法要寫在構(gòu)造函數(shù)的prototype屬性上。
因?yàn)槊看蝿?chuàng)建實(shí)例的時(shí)候會(huì)new 構(gòu)造函數(shù)呆万,是對(duì)構(gòu)造函數(shù)中實(shí)例變量商源,實(shí)例方法的一次完全復(fù)制。而方法都是在做完全一樣的功能谋减,沒(méi)有必要復(fù)制那么多次牡彻,于是就統(tǒng)一寫在了構(gòu)造函數(shù)的prototype上。
屬性寫在this.xxx里面出爹,是為了屬性私有庄吼。每個(gè)實(shí)例都有它特定的屬性,new 構(gòu)造函數(shù)的時(shí)候通過(guò)參數(shù)傳入屬性严就。
- 讓屬性支持傳參數(shù)進(jìn)行控制总寻,不寫死。
- 查找原型鏈更耗費(fèi)時(shí)間盈蛮。(其實(shí)完全可以忽略)
內(nèi)部原型引用
對(duì)象中保存原型的變量废菱,也被稱之為內(nèi)部原型引用(the internal prototype link),歷史上也曾稱之為 __proto__
抖誉,對(duì)這個(gè)稱謂始終存在一些爭(zhēng)議殊轴。 更精確的,它可以被稱為 Object.getPrototypeOf(...) 的返回值袒炉。
constructor
注:constructor屬性并非一定指向構(gòu)造函數(shù)旁理,他也是可以修改、變更的我磁。