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 相关文章推荐
jQuery 遍历-nextUntil()方法以及prevUntil()方法的使用介绍
Apr 26 Javascript
js实现的常用的左侧导航效果
Oct 17 Javascript
ExtJS判断IE浏览器类型的方法
Feb 10 Javascript
使用CDN和AJAX加速WordPress中jQuery的加载
Dec 05 Javascript
基于jQuery下拉选择框插件支持单选多选功能代码
Jun 07 Javascript
深入浅析javascript中的作用域(推荐)
Jul 19 Javascript
JS获取input file绝对路径的方法(推荐)
Aug 02 Javascript
Bootstrap滚动监听组件scrollspy.js使用方法详解
Jul 20 Javascript
jQuery实现checkbox的简单操作
Nov 18 jQuery
微信小程序云开发 搭建一个管理小程序
May 17 Javascript
vue 使用async写数字动态加载效果案例
Jul 18 Javascript
解决pycharm双击但是无法打开的情况
Oct 31 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
用IE远程创建Mysql数据库的简易程序
2006/10/09 PHP
php使HTML标签自动补全闭合函数代码
2012/10/04 PHP
php 在线导入mysql大数据程序
2015/06/11 PHP
php二维码生成
2015/10/19 PHP
golang与php实现计算两个经纬度之间距离的方法
2016/07/22 PHP
Javascript面象对象成员、共享成员变量实验
2010/11/19 Javascript
js自定义事件及事件交互原理概述(一)
2013/02/01 Javascript
js实现图片旋转的三种方法
2014/04/10 Javascript
jQuery实现的网页左侧在线客服效果代码
2015/10/23 Javascript
AngularJS转换响应内容
2016/01/27 Javascript
动态设置form表单的action属性的值的简单方法
2016/05/25 Javascript
浅谈JavaScript前端开发的MVC结构与MVVM结构
2016/06/03 Javascript
jQuery 全选 全部选 反选 实现代码
2016/08/17 Javascript
Vuejs第十篇之vuejs父子组件通信
2016/09/06 Javascript
ajax分页效果(bootstrap模态框)
2017/01/23 Javascript
基于JavaScript实现轮播图原理及示例
2020/04/10 Javascript
js读取json文件片段中的数据实例
2017/03/09 Javascript
Angular中ng-bind和ng-model的区别实例详解
2017/04/10 Javascript
JavaScript数据类型和变量_动力节点Java学院整理
2017/06/26 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
2017/06/28 Javascript
Javascript中 toFixed四舍六入方法
2017/08/21 Javascript
Angular Material Icon使用详解
2018/11/07 Javascript
JS事件绑定的常用方式实例总结
2019/03/02 Javascript
vue-video-player 解决微信自动全屏播放问题(横竖屏导致样式错乱问题)
2020/02/25 Javascript
基于VUE实现判断设备是PC还是移动端
2020/07/03 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
2020/07/22 Javascript
Python列表推导式的使用方法
2013/11/21 Python
python按比例随机切分数据的实现
2019/07/11 Python
Python中一个for循环循环多个变量的示例
2019/07/16 Python
Python网络编程之使用TCP方式传输文件操作示例
2019/11/01 Python
python如何导入依赖包
2020/07/13 Python
投资合作协议书范本
2014/04/17 职场文书
2014年党建工作总结
2014/11/11 职场文书
结婚通知短信大全
2015/04/17 职场文书
2015年扫黄打非工作总结
2015/05/13 职场文书
浅谈如何提高PHP代码质量之端到端集成测试
2021/05/28 PHP