DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> js constructor的實際作用分析
js constructor的實際作用分析
編輯:關於JavaScript     
復制代碼 代碼如下:
<script> Function.prototype.createInstance = function(){
var T = function(){};
T.prototype = this.prototype;
T.constructor = this;
var o = new T();
this.apply(o, arguments);
return o;
}</script>

說下上面代碼裡面 T.constructor = this這句話,我感覺這句話沒有什麼實際作用,
本身T.constructor應該是為Funtion,為什麼要給它設定為Funtion的實例呢,
復制代碼 代碼如下:
<script>
Function.prototype.$extends = function(p){
this.$super = p;
var fn = function(){};
fn.prototype = p.prototype;
this.prototype = new fn();
//這句是我自己加的,保證構造出子類實例的constructor依然指向子類的構造器函數
this.prototype.constructor=this;
//-----------------------------
return this;
};
function Animal(){
}
function Cat(){
}
Cat.$extends(Animal);
var bb=new Cat();
alert(bb.constructor);
//但是(this.prototype.constructor=this)這種做法通過bb這個對象無法回朔到Animal的原型
//下面語句依然返回Cat這個函數,而不是Animal
alert(bb.constructor.prototype.constructor)
</script>

還有上面這句代碼,我自己加了1句,修正了子類構造器依然指向子類函數,但是對象的原型鏈的回朔不能到達父類原型,解決辦法是
去掉this.prototype.constructor=this;既不給原型設置constructor屬性,而是給實例設置一個constructor屬性,如下代碼
復制代碼 代碼如下:
<script>
Function.prototype.$extends = function(p){
this.$super = p;
var fn = function(){};
fn.prototype = p.prototype;
this.prototype = new fn();
return this;
};
function Animal(){
}
function Cat(){
this.constructor= arguments.callee;
}
Cat.$extends(Animal);
var bb=new Cat();
alert(bb.constructor);
//這種做法可以通過bb這個對象回朔到Animal的原型
alert(bb.constructor.prototype.constructor)
</script>

最後分析下constructor的實際作用
復制代碼 代碼如下:
<script>
//定義函數
var f=function(){
}
//這裡顯示true,因為f的構造器是Funtion,f內部的原型屬性_proto_被賦值為構造器的prototype也就是Function的prototype
//instanceof檢查f內部的_proto_是否與Function.prototype有共同的結點,如果有則返回true
alert(f instanceof Function)
//obj是f的實例
var obj=new f;
//obj內部的原型屬性_proto_在new f時被賦值為f.prototype,顯然f.prototype與Function.prototype沒有共同的結點,因此顯示false
alert(obj instanceof Function)
//為了讓obj成為Function的實例也就是(obj instanceof Function)顯示true
//只需要f.prototype=Function.prototype
f.prototype=Function.prototype;
//但是我不推薦上面這種做法,因為對f.prototype的修改會破壞了Function.prototype,例如f.prototype.name="51js"會給Function的原型也加上1個name屬性
//正確的做法應該是下面這樣,這樣諸如f.prototype.name的修改就不會破壞Function的原型了
f.prototype=new Function();
f.prototype.name="zhouyang";
/**關鍵是這裡,再次調整constructor屬性為f,維護constructor這種做法是為了保證obj能夠正確回朔原型鏈,
*假如我們要獲取obj內部的原型鏈,但只知道obj,不知道obj是怎麼實例化來的,由於obj內部的_proto_屬性不可見,那麼我們要獲取obj內部原形只能通過obj.constructor來獲取構造器,然後再獲取構造器的prototype
*1.如果我們加下面這句(f.prototype.constructor=f),回朔obj原型鏈
*只能回朔1層原型鏈也就是obj.constructor.prototype(子類原型)-->obj.constructor.prototype.constructor.prototype(依然是子類原型),這樣只能回朔1層原型鏈
**/
f.prototype.constructor=f;
obj=new f;
alert("找到子類了---"+obj.constructor+"\n"
+"找到的還是子類,無法找到父類---"+obj.constructor.prototype.constructor)
alert(obj instanceof Function)
/**2.如果我們用下面的方法在f定義裡設置f的實例的constructor,而不是f原型的constructor
*就可以回朔2層原型鏈也就是 obj.constructor.prototype(子類原型)-->obj.constructor.prototype.constructor.prototype(父類原型)
*顯然這種情況是符合對象原型繼承鏈的情況的
*/
f=function(){
this.constructor=arguments.callee;
}
f.prototype=new Function();
f.prototype.name="zhouyang";
obj=new f;
alert("找到子類了---"+obj.constructor+"\n"
+"找到父類了---"+obj.constructor.prototype.constructor)
alert(obj instanceof Function)
</script>

復制代碼 代碼如下:
<script>
//定義函數
var f=function(){
}
//這裡顯示true,因為f的構造器是Funtion,f內部的原型屬性_proto_被賦值為構造器的prototype也就是Function的prototype
//instanceof檢查f內部的_proto_是否與Function.prototype有共同的結點,如果有則返回true
alert(f instanceof Function)
//obj是f的實例
var obj=new f;
//obj內部的原型屬性_proto_在new f時被賦值為f.prototype,顯然f.prototype與Function.prototype沒有共同的結點,因此顯示false
alert(obj instanceof Function)
//為了讓obj成為Function的實例也就是(obj instanceof Function)顯示true
//只需要f.prototype=Function.prototype
f.prototype=Function.prototype;
//但是我不推薦上面這種做法,因為對f.prototype的修改會破壞了Function.prototype,例如f.prototype.name="51js"會給Function的原型也加上1個name屬性
//正確的做法應該是下面這樣,這樣諸如f.prototype.name的修改就不會破壞Function的原型了
f.prototype=new Function();
f.prototype.name="zhouyang";
/**關鍵是這裡,再次調整constructor屬性為f,維護constructor這種做法是為了保證obj能夠正確回朔原型鏈,
*假如我們要獲取obj內部的原型鏈,但只知道obj,不知道obj是怎麼實例化來的,由於obj內部的_proto_屬性不可見,那麼我們要獲取obj內部原形只能通過obj.constructor來獲取構造器,然後再獲取構造器的prototype
*1.如果我們加下面這句(f.prototype.constructor=f),回朔obj原型鏈
*只能回朔1層原型鏈也就是obj.constructor.prototype(子類原型)-->obj.constructor.prototype.constructor.prototype(依然是子類原型),這樣只能回朔1層原型鏈
**/
f.prototype.constructor=f;
obj=new f;
alert("找到子類了---"+obj.constructor+"\n"
+"找到的還是子類,無法找到父類---"+obj.constructor.prototype.constructor)
alert(obj instanceof Function)
/**2.如果我們用下面的方法在f定義裡設置f的實例的constructor,而不是f原型的constructor
*就可以回朔2層原型鏈也就是 obj.constructor.prototype(子類原型)-->obj.constructor.prototype.constructor.prototype(父類原型)
*顯然這種情況是符合對象原型繼承鏈的情況的
*/
f=function(){
this.constructor=arguments.callee;
}
f.prototype=new Function();
f.prototype.name="zhouyang";
obj=new f;
alert("找到子類了---"+obj.constructor+"\n"
+"找到父類了---"+obj.constructor.prototype.constructor)
alert(obj instanceof Function)
</script>結論constructor的作用就是維護對象的原型鏈

向果果和winter賜教一下,不知理解的是否正確哈,另外我看大家常說的原型的污染到底指的是什麼??
作用的話下面這個或許可以說明
復制代碼 代碼如下:
<script>
var f = function(x){}
f.prototype={};
alert((new f).constructor);
f.prototype.constructor=f;
alert((new f).constructor);
</script>
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved