jsconstructor的实际作用分析
分析 作用 实际
2023-06-13 09:14:31 时间
<script>Function.prototype.createInstance=function(){
varT=function(){};
T.prototype=this.prototype;
T.constructor=this;
varo=newT();
this.apply(o,arguments);
returno;
}</script>
说下上面代码里面T.constructor=this这句话,我感觉这句话没有什么实际作用,
本身T.constructor应该是为Funtion,为什么要给它设定为Funtion的实例呢,
<script>
Function.prototype.$extends=function(p){
this.$super=p;
varfn=function(){};
fn.prototype=p.prototype;
this.prototype=newfn();
//这句是我自己加的,保证构造出子类实例的constructor依然指向子类的构造器函数
this.prototype.constructor=this;
//-----------------------------
returnthis;
};
functionAnimal(){
}
functionCat(){
}
Cat.$extends(Animal);
varbb=newCat();
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;
varfn=function(){};
fn.prototype=p.prototype;
this.prototype=newfn();
returnthis;
};
functionAnimal(){
}
functionCat(){
this.constructor=arguments.callee;
}
Cat.$extends(Animal);
varbb=newCat();
alert(bb.constructor);
//这种做法可以通过bb这个对象回朔到Animal的原型
alert(bb.constructor.prototype.constructor)
</script>
最后分析下constructor的实际作用
<script>
//定义函数
varf=function(){
}
//这里显示true,因为f的构造器是Funtion,f内部的原型属性_proto_被赋值为构造器的prototype也就是Function的prototype
//instanceof检查f内部的_proto_是否与Function.prototype有共同的结点,如果有则返回true
alert(finstanceofFunction)
//obj是f的实例
varobj=newf;
//obj内部的原型属性_proto_在newf时被赋值为f.prototype,显然f.prototype与Function.prototype没有共同的结点,因此显示false
alert(objinstanceofFunction)
//为了让obj成为Function的实例也就是(objinstanceofFunction)显示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=newFunction();
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=newf;
alert("找到子类了---"+obj.constructor+"\n"
+"找到的还是子类,无法找到父类---"+obj.constructor.prototype.constructor)
alert(objinstanceofFunction)
/**2.如果我们用下面的方法在f定义里设置f的实例的constructor,而不是f原型的constructor
*就可以回朔2层原型链也就是obj.constructor.prototype(子类原型)-->obj.constructor.prototype.constructor.prototype(父类原型)
*显然这种情况是符合对象原型继承链的情况的
*/
f=function(){
this.constructor=arguments.callee;
}
f.prototype=newFunction();
f.prototype.name="zhouyang";
obj=newf;
alert("找到子类了---"+obj.constructor+"\n"
+"找到父类了---"+obj.constructor.prototype.constructor)
alert(objinstanceofFunction)
</script>
<script>
//定义函数
varf=function(){
}
//这里显示true,因为f的构造器是Funtion,f内部的原型属性_proto_被赋值为构造器的prototype也就是Function的prototype
//instanceof检查f内部的_proto_是否与Function.prototype有共同的结点,如果有则返回true
alert(finstanceofFunction)
//obj是f的实例
varobj=newf;
//obj内部的原型属性_proto_在newf时被赋值为f.prototype,显然f.prototype与Function.prototype没有共同的结点,因此显示false
alert(objinstanceofFunction)
//为了让obj成为Function的实例也就是(objinstanceofFunction)显示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=newFunction();
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=newf;
alert("找到子类了---"+obj.constructor+"\n"
+"找到的还是子类,无法找到父类---"+obj.constructor.prototype.constructor)
alert(objinstanceofFunction)
/**2.如果我们用下面的方法在f定义里设置f的实例的constructor,而不是f原型的constructor
*就可以回朔2层原型链也就是obj.constructor.prototype(子类原型)-->obj.constructor.prototype.constructor.prototype(父类原型)
*显然这种情况是符合对象原型继承链的情况的
*/
f=function(){
this.constructor=arguments.callee;
}
f.prototype=newFunction();
f.prototype.name="zhouyang";
obj=newf;
alert("找到子类了---"+obj.constructor+"\n"
+"找到父类了---"+obj.constructor.prototype.constructor)
alert(objinstanceofFunction)
</script>结论constructor的作用就是维护对象的原型链
向果果和winter赐教一下,不知理解的是否正确哈,另外我看大家常说的原型的污染到底指的是什么??
作用的话下面这个或许可以说明
<script>
varf=function(x){}
f.prototype={};
alert((newf).constructor);
f.prototype.constructor=f;
alert((newf).constructor);
</script>
相关文章
- QCon大会实录:PB级数据秒级分析-腾讯云原生湖仓DLC架构揭秘
- accessors 作用_EasyExcel与@Accessors(chain = true)不兼容分析
- RNA-seq 详细教程:时间点分析(14)
- react源码分析--组件的创建和更新
- View的滑动冲突的分析和处理实践
- 这玩意儿能逆向分析代码,我直接麻了!
- SAP UI5 Fiori 应用在启动时向 ABAP 后台发起的 OData 请求序列的顺序和作用分析
- webpack原理(3):Tapable源码分析及钩子函数作用分析
- 【Android Gradle 插件】Android 依赖管理 ④ ( 常用依赖配置分析 | implementation 依赖作用 | api 依赖作用 | compileOnly 依赖作用 )
- 网站日志分析:ip地址出现次数统计
- 函数分析Linux中atoi函数的作用(linuxatoi)
- Linux 启动过程及内核加载分析(linux启动内核)
- 利用Oracle表分析挖掘信息(oracle表分析的作用)
- 分析Linux系统日志信息:探究Out文件的作用(linuxout文件)
- Redis数据库中的 px 过期参数的作用分析(redispx)
- MySQL卡硬盘性能分析(mysql 卡硬盘)
- MySQL的作用及应用场景分析(mysql 中 作用)
- 分析Redis集群架构一图解释一切(redis集群结构图解)
- Oracle FM FX 飞速数据库管理和分析利器(oracle fm fx)
- 解决Java调用BAT批处理不弹出cmd窗口的方法分析
- 浅谈php中mysql与mysqli的区别分析
- ImageView的属性android:scaleType的作用分析
- JoshChen_web格式编码UTF8-无BOM的小细节分析
- 实例分析javascript中的call()和apply()方法