<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>原型陷阱</title>
<meta name="description" content="">
<meta name="keywords" content="">
<style type="text/css">
</style>
</head>
<body>
<script type="text/javascript">
//当我们对原型对象执行完全替换时,可能会触发原型链中某种异常
//prototype.constructor属性是不可靠的
function Dog(){
this.tail=true;
}
var benji=new Dog();
var rusty=new Dog();
Dog.prototype.say=function(){
return "Woof!";
}
benji.say();//Woof!
rusty.say();//Woof!
benji.constructor===Dog; //true
rusty.constructor===Dog; //true
//现在,我们用一个自定义的新对象完全覆盖掉原有的原型对象
Dog.prototype={
paws: 4,
hair: true
}
//事实证明,这会使原有对象不能访问原型的新增属性,它们依然通过那个神秘的链接
//与原有属性对象保持联系。
typeof benji.paws; //undefined
benji.say(); //Woof!
typeof benji._proto_.say; //function
typeof benji_proto_.paws; //undefined
//而我们之后创建的所有对象使用的都是被更新后的prototype对象
var lucy=new Dog();
lucy.say(); //TypeError: lucy.say is not a function
lucy.paws; //4
//并且新的对象秘密链接_proto_也指向了新的prototype对象
typeof lucy._proto_.say; //undefined
typeof lucy._proto_.paws; //number
//但这时候,新对象的constructor属性就不能再保持正确了,原本应该是Dog()的引用
// 却指向了Object()
lucy.constructor; // function Object(){[native code]}
benji.constructor; //function Dog() {this.tail=true;}
//当然,我们可以通过重新设置constructor属性来解决上述所有的异常行为:
function Dog(){}
Dog.prototype={};
new Dog().constructor===Dog; //false
Dog.prototype.constructor=Dog;
new Dog().constructor===Dog; //true
//当我们重写某对象的prototype时,需要重置相应的constructor属性
</script>
</body>
</html>
js中prototype的陷阱
最新推荐文章于 2021-11-26 10:12:14 发布