首页 >web前端 >js教程 >js constructor的实际作用分析_javascript技巧

js constructor的实际作用分析_javascript技巧

WBOY
WBOY原创
2016-05-16 17:59:351281浏览
复制代码 代码如下:

<script> Function.prototype.createInstance = function(){ <BR>var T = function(){}; <BR>T.prototype = this.prototype; <BR>T.constructor = this; <BR>var o = new T(); <BR>this.apply(o, arguments); <BR>return o; <BR>}</script>

说下上面代码里面 T.constructor = this这句话,我感觉这句话没有什么实际作用,
本身T.constructor应该是为Funtion,为什么要给它设定为Funtion的实例呢,
复制代码 代码如下:

<script> <BR>Function.prototype.$extends = function(p){ <BR>this.$super = p; <BR>var fn = function(){}; <BR>fn.prototype = p.prototype; <BR>this.prototype = new fn(); <BR>//这句是我自己加的,保证构造出子类实例的constructor依然指向子类的构造器函数 <BR>this.prototype.constructor=this; <BR>//----------------------------- <BR>return this; <BR>}; <BR>function Animal(){ <BR>} <BR>function Cat(){ <BR>} <BR>Cat.$extends(Animal); <BR>var bb=new Cat(); <BR>alert(bb.constructor); <BR>//但是(this.prototype.constructor=this)这种做法通过bb这个对象无法回朔到Animal的原型 <BR>//下面语句依然返回Cat这个函数,而不是Animal <BR>alert(bb.constructor.prototype.constructor) <BR></script>

还有上面这句代码,我自己加了1句,修正了子类构造器依然指向子类函数,但是对象的原型链的回朔不能到达父类原型,解决办法是
去掉this.prototype.constructor=this;既不给原型设置constructor属性,而是给实例设置一个constructor属性,如下代码
复制代码 代码如下:

<script> <BR>Function.prototype.$extends = function(p){ <BR>this.$super = p; <BR>var fn = function(){}; <BR>fn.prototype = p.prototype; <BR>this.prototype = new fn(); <BR>return this; <BR>}; <BR>function Animal(){ <BR>} <BR>function Cat(){ <BR>this.constructor= arguments.callee; <BR>} <BR>Cat.$extends(Animal); <BR>var bb=new Cat(); <BR>alert(bb.constructor); <BR>//这种做法可以通过bb这个对象回朔到Animal的原型 <BR>alert(bb.constructor.prototype.constructor) <BR></script>

最后分析下constructor的实际作用
复制代码 代码如下:

<script> <BR>//定义函数 <BR>var f=function(){ <BR>} <BR>//这里显示true,因为f的构造器是Funtion,f内部的原型属性_proto_被赋值为构造器的prototype也就是Function的prototype <BR>//instanceof检查f内部的_proto_是否与Function.prototype有共同的结点,如果有则返回true <BR>alert(f instanceof Function) <BR>//obj是f的实例 <BR>var obj=new f; <BR>//obj内部的原型属性_proto_在new f时被赋值为f.prototype,显然f.prototype与Function.prototype没有共同的结点,因此显示false <BR>alert(obj instanceof Function) <BR>//为了让obj成为Function的实例也就是(obj instanceof Function)显示true <BR>//只需要f.prototype=Function.prototype <BR>f.prototype=Function.prototype; <BR>//但是我不推荐上面这种做法,因为对f.prototype的修改会破坏了Function.prototype,例如f.prototype.name="51js"会给Function的原型也加上1个name属性 <BR>//正确的做法应该是下面这样,这样诸如f.prototype.name的修改就不会破坏Function的原型了 <BR>f.prototype=new Function(); <BR>f.prototype.name="zhouyang"; <BR>/**关键是这里,再次调整constructor属性为f,维护constructor这种做法是为了保证obj能够正确回朔原型链, <BR>*假如我们要获取obj内部的原型链,但只知道obj,不知道obj是怎么实例化来的,由于obj内部的_proto_属性不可见,那么我们要获取obj内部原形只能通过obj.constructor来获取构造器,然后再获取构造器的prototype <BR>*1.如果我们加下面这句(f.prototype.constructor=f),回朔obj原型链 <BR>*只能回朔1层原型链也就是obj.constructor.prototype(子类原型)-->obj.constructor.prototype.constructor.prototype(依然是子类原型),这样只能回朔1层原型链 <BR>**/ <BR>f.prototype.constructor=f; <BR>obj=new f; <BR>alert("找到子类了---"+obj.constructor+"\n" <BR>+"找到的还是子类,无法找到父类---"+obj.constructor.prototype.constructor) <BR>alert(obj instanceof Function) <BR>/**2.如果我们用下面的方法在f定义里设置f的实例的constructor,而不是f原型的constructor <BR>*就可以回朔2层原型链也就是 obj.constructor.prototype(子类原型)-->obj.constructor.prototype.constructor.prototype(父类原型) <BR>*显然这种情况是符合对象原型继承链的情况的 <BR>*/ <BR>f=function(){ <BR>this.constructor=arguments.callee; <BR>} <BR>f.prototype=new Function(); <BR>f.prototype.name="zhouyang"; <BR>obj=new f; <BR>alert("找到子类了---"+obj.constructor+"\n" <BR>+"找到父类了---"+obj.constructor.prototype.constructor) <BR>alert(obj instanceof Function) <BR></script>

复制代码 代码如下:

<script> <BR>//定义函数 <BR>var f=function(){ <BR>} <BR>//这里显示true,因为f的构造器是Funtion,f内部的原型属性_proto_被赋值为构造器的prototype也就是Function的prototype <BR>//instanceof检查f内部的_proto_是否与Function.prototype有共同的结点,如果有则返回true <BR>alert(f instanceof Function) <BR>//obj是f的实例 <BR>var obj=new f; <BR>//obj内部的原型属性_proto_在new f时被赋值为f.prototype,显然f.prototype与Function.prototype没有共同的结点,因此显示false <BR>alert(obj instanceof Function) <BR>//为了让obj成为Function的实例也就是(obj instanceof Function)显示true <BR>//只需要f.prototype=Function.prototype <BR>f.prototype=Function.prototype; <BR>//但是我不推荐上面这种做法,因为对f.prototype的修改会破坏了Function.prototype,例如f.prototype.name="51js"会给Function的原型也加上1个name属性 <BR>//正确的做法应该是下面这样,这样诸如f.prototype.name的修改就不会破坏Function的原型了 <BR>f.prototype=new Function(); <BR>f.prototype.name="zhouyang"; <BR>/**关键是这里,再次调整constructor属性为f,维护constructor这种做法是为了保证obj能够正确回朔原型链, <BR>*假如我们要获取obj内部的原型链,但只知道obj,不知道obj是怎么实例化来的,由于obj内部的_proto_属性不可见,那么我们要获取obj内部原形只能通过obj.constructor来获取构造器,然后再获取构造器的prototype <BR>*1.如果我们加下面这句(f.prototype.constructor=f),回朔obj原型链 <BR>*只能回朔1层原型链也就是obj.constructor.prototype(子类原型)-->obj.constructor.prototype.constructor.prototype(依然是子类原型),这样只能回朔1层原型链 <BR>**/ <BR>f.prototype.constructor=f; <BR>obj=new f; <BR>alert("找到子类了---"+obj.constructor+"\n" <BR>+"找到的还是子类,无法找到父类---"+obj.constructor.prototype.constructor) <BR>alert(obj instanceof Function) <BR>/**2.如果我们用下面的方法在f定义里设置f的实例的constructor,而不是f原型的constructor <BR>*就可以回朔2层原型链也就是 obj.constructor.prototype(子类原型)-->obj.constructor.prototype.constructor.prototype(父类原型) <BR>*显然这种情况是符合对象原型继承链的情况的 <BR>*/ <BR>f=function(){ <BR>this.constructor=arguments.callee; <BR>} <BR>f.prototype=new Function(); <BR>f.prototype.name="zhouyang"; <BR>obj=new f; <BR>alert("找到子类了---"+obj.constructor+"\n" <BR>+"找到父类了---"+obj.constructor.prototype.constructor) <BR>alert(obj instanceof Function) <BR></script>结论constructor的作用就是维护对象的原型链

向果果和winter赐教一下,不知理解的是否正确哈,另外我看大家常说的原型的污染到底指的是什么??
作用的话下面这个或许可以说明
复制代码 代码如下:

<script> <BR>var f = function(x){} <BR>f.prototype={}; <BR>alert((new f).constructor); <BR>f.prototype.constructor=f; <BR>alert((new f).constructor); <BR></script>
声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn