js constructor的实际作用分析

 更新时间:2011年11月15日 01:37:47   作者:  
大家讨论下constructor的作用哈,需要的朋友可以参考下。从51js摘编而来。
复制代码 代码如下:

<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>

相关文章

  • 纯JS代码实现隔行变色鼠标移入高亮

    纯JS代码实现隔行变色鼠标移入高亮

    这篇文章主要介绍了纯JS代码实现隔行变色鼠标移入高亮的相关资料,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2016-11-11
  • 详解js访问对象的属性和方法

    详解js访问对象的属性和方法

    在本篇文章里我们给大家分享了关于js访问对象的属性和方法的相关知识点,有需要的朋友们可以学习下。
    2018-10-10
  • 浅谈JavaScript中指针和地址

    浅谈JavaScript中指针和地址

    Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象。Javascript可以通过一定的设计模式来实现面向对象的编程,其中this指针就是实现面向对象的一个很重要的特性。
    2015-07-07
  • 微信小程序实现蓝牙打印

    微信小程序实现蓝牙打印

    这篇文章主要为大家详细介绍了微信小程序实现蓝牙打印,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • 全解跨域请求问题处理方法及分析

    全解跨域请求问题处理方法及分析

    这篇文章主要为大家介绍了全解跨域请求问题处理方法及分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2023-07-07
  • javascript写的简单的计算器,内容很多,方法实用,推荐

    javascript写的简单的计算器,内容很多,方法实用,推荐

    最近用javascript写了一个简单的计算器,自己测试感觉还好,代码都给了注释,非常不错,推荐大家学习。
    2011-12-12
  • 基于Fixed定位的框选功能的实现代码

    基于Fixed定位的框选功能的实现代码

    这篇文章主要介绍了基于Fixed定位的框选功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • element-ui的表单验证清除校验提示语的解决方案

    element-ui的表单验证清除校验提示语的解决方案

    对表单域中的数据进行校验的时候,其中有一项比较特殊,不是简单的输入框,下拉框这些表单元素,而是自己写的一个el-table的选择弹窗,本文给大家介绍element-ui的表单验证如何清除校验提示语,感兴趣的朋友一起看看吧
    2024-01-01
  • js改变style样式和css样式的简单实例

    js改变style样式和css样式的简单实例

    下面小编就为大家带来一篇js改变style样式和css样式的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • 用js写了一个类似php的print_r输出换行功能

    用js写了一个类似php的print_r输出换行功能

    因为php的print_r比较好用同时js却没有这个功能于是自己就写了一个,感兴趣的你可不要错过了哈,希望本文对你提高知识有所帮助
    2013-02-02

最新评论