js constructor的实际作用分析


Posted in Javascript onNovember 15, 2011
<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>
Javascript 相关文章推荐
javascript 面向对象编程 聊聊对象的事
Sep 17 Javascript
js的写法基础分析
Jan 17 Javascript
Seajs 简易文档 提供简单、极致的模块化开发体验
Apr 13 Javascript
JS实现左右无缝轮播图代码
May 01 Javascript
14 个折磨人的 JavaScript 面试题
Aug 08 Javascript
使用JS正则表达式 替换括号,尖括号等
Nov 29 Javascript
javascript中的try catch异常捕获机制用法分析
Dec 14 Javascript
微信小程序 PHP生成带参数二维码
Feb 21 Javascript
vue项目常用组件和框架结构介绍
Dec 24 Javascript
如何更好的编写js async函数
May 13 Javascript
利用npm 安装删除模块的方法
May 15 Javascript
vue中axios防止多次触发终止多次请求的示例代码(防抖)
Feb 16 Javascript
浅谈Javascript面向对象编程
Nov 15 #Javascript
js Html结构转字符串形式显示代码
Nov 15 #Javascript
Js 时间间隔计算的函数(间隔天数)
Nov 15 #Javascript
jQuery源码分析-05异步队列 Deferred 使用介绍
Nov 14 #Javascript
jQuery源码分析-04 选择器-Sizzle-工作原理分析
Nov 14 #Javascript
jQuery源码分析-03构造jQuery对象-工具函数
Nov 14 #Javascript
jQuery源码分析-03构造jQuery对象-源码结构和核心函数
Nov 14 #Javascript
You might like
动态生成gif格式的图像要注意?
2006/10/09 PHP
PHP常用函数之获取汉字首字母功能示例
2019/10/21 PHP
关于JavaScript的gzip静态压缩方法
2007/01/05 Javascript
window.onbeforeunload方法在IE下无法正常工作的解决办法
2010/01/23 Javascript
javascript css styleFloat和cssFloat
2010/03/15 Javascript
jQuery 获取、设置HTML或TEXT内容的两种方法
2014/05/23 Javascript
Javascript字符串对象的常用方法简明版
2014/06/26 Javascript
jQuery中clearQueue()方法用法实例
2014/12/29 Javascript
使用JQuery实现智能表单验证功能
2016/03/08 Javascript
js 截取或者替换字符串中的数字实现方法
2016/06/13 Javascript
javascript 中的console.log和弹出窗口alert
2016/08/30 Javascript
jquery radio的取值_radio的选中_radio的重置方法
2016/09/20 Javascript
JS简单获取当前日期和农历日期的方法
2017/04/17 Javascript
vue 中滚动条始终定位在底部的方法
2018/09/03 Javascript
浅谈Webpack多页应用HMR卡住问题
2019/04/24 Javascript
这样回答继承可能面试官更满意
2019/12/10 Javascript
vue实现信息管理系统
2020/05/30 Javascript
Python中使用PDB库调试程序
2015/04/05 Python
详解Python中的循环语句的用法
2015/04/09 Python
python3使用matplotlib绘制散点图
2019/03/19 Python
解决django中form表单设置action后无法回到原页面的问题
2020/03/13 Python
聪明的粉丝购买门票的地方:TickPick
2018/03/09 全球购物
牧马人澳大利亚官网:Wrangler澳大利亚
2019/10/08 全球购物
英国奢侈品牌时尚购物平台:Farfetch(支持中文)
2020/02/18 全球购物
房地产融资计划书
2014/01/10 职场文书
高等教育学自荐书范文
2014/02/10 职场文书
企业文化建设实施方案
2014/03/22 职场文书
解除合同协议书
2014/04/17 职场文书
社区禁毒工作方案
2014/06/02 职场文书
生日庆典策划方案
2014/06/02 职场文书
政治学专业毕业生求职信
2014/08/11 职场文书
交通事故协议书范文
2014/10/23 职场文书
2014年四风个人对照检查及整改措施
2014/10/28 职场文书
如何使JavaScript休眠或等待
2021/04/27 Javascript
使用golang编写一个并发工作队列
2021/05/08 Golang
SpringBoot全局异常处理方案分享
2022/05/25 Java/Android