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 相关文章推荐
JSON语法五大要素图文介绍
Dec 04 Javascript
asm.js使用示例代码
Nov 28 Javascript
解析Javascript中中括号“[]”的多义性
Dec 03 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
Dec 04 Javascript
每天一篇javascript学习小结(Date对象)
Nov 13 Javascript
ajax跨域调用webservice的实现代码
May 09 Javascript
详解JavaScript数组过滤相同元素的5种方法
May 23 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
Jun 28 Javascript
详解Vue2.x-directive的学习笔记
Jul 17 Javascript
vue脚手架及vue-router基本使用
Apr 09 Javascript
vue watch关于对象内的属性监听
Apr 22 Javascript
AJAX XMLHttpRequest对象创建使用详解
Aug 20 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
虫族 Zerg 热键控制
2020/03/14 星际争霸
PHP多例模式介绍
2013/06/24 PHP
php实现的Cookies操作类实例
2014/09/24 PHP
php删除文本文件中重复行的方法
2015/04/28 PHP
非常实用的php验证码类
2016/05/15 PHP
解决laravel-admin 自己新建页面里 js 需要刷新一次的问题
2019/10/03 PHP
JavaScript 原型与继承说明
2010/06/09 Javascript
基于jQuery的淡入淡出可自动切换的幻灯插件
2010/08/24 Javascript
关于图片按比例自适应缩放的js代码
2011/10/30 Javascript
jQuery中使用Ajax获取JSON格式数据示例代码
2013/11/26 Javascript
js中判断对象是否为空的三种实现方法
2013/12/23 Javascript
NodeJS中利用Promise来封装异步函数
2015/02/25 NodeJs
学习JavaScript设计模式之享元模式
2016/01/18 Javascript
基于JavaScript实现百叶窗动画效果不只单纯flas可以实现
2016/02/29 Javascript
JS判断元素是否在数组内的实现代码
2016/03/30 Javascript
Bootstrap3制作搜索框样式的方法
2016/07/11 Javascript
js HTML5多图片上传及预览实例解析(不含前端的文件分割)
2016/08/26 Javascript
Angular和百度地图的结合实例代码
2016/10/19 Javascript
javascript轮播图算法
2016/10/21 Javascript
react项目实践之webpack-dev-serve
2018/09/14 Javascript
vue源码中的检测方法的实现
2019/09/26 Javascript
Openlayers绘制聚合标注
2020/09/28 Javascript
以windows service方式运行Python程序的方法
2015/06/03 Python
详解python 发送邮件实例代码
2016/12/22 Python
Python向MySQL批量插数据的实例讲解
2018/03/31 Python
python集合的创建、添加及删除操作示例
2019/10/08 Python
浅析python,PyCharm,Anaconda三者之间的关系
2019/11/27 Python
Python为何不支持switch语句原理详解
2020/10/21 Python
python读取图片颜色值并生成excel像素画的方法实例
2021/02/19 Python
HTML5拖拉上传文件的简单实例
2017/01/11 HTML / CSS
Html5 APP中监听返回事件处理的方法示例
2018/03/15 HTML / CSS
世界上最大的艺术和工艺用品商店:MisterArt.com
2018/07/13 全球购物
网页美工求职信范文
2014/04/17 职场文书
《傅雷家书》教学反思
2014/04/20 职场文书
商业街策划方案
2014/05/31 职场文书
2016公务员年度考核评语
2015/12/01 职场文书