首页 > 代码库 > 原型陷阱
原型陷阱
处理原型问题时,我们需要特别注意一下两种行为。
1、当我们对原型对象执行完全替换时,可能会触发原型链中的某种异常
2、prototype。constructor属性是不可靠的
下面,我们来新建一个简单的构造器函数,并用它再创建两个对象;
function Dog() {
this.tail = true;
}
var benji = new Dog();
var rusty = new Dog();
/*
* 即便在benji和rusty对象创建之后,我们也依然能为Dog();的原型添加属性,并且在属性被添加之前就已经存在的对象
* 也可以随时访问这些新属性。现在,让我们放一个say()方法进去*/
Dog.prototype.say = function () {
return ‘Woof‘;
};
/*这样,上面的两个对象都可以访问该新方法了;*/
console.log(benji.say());//Woof
console.log(rusty.say());//Woof
/*检查一下这些对象的构造器函数,就会发现一切正常*/
console.log(benji.constructor === Dog); //true
console.log(rusty.constructor === Dog); //true
/*现在我们用一个新对象完全覆盖掉原有的原型对象;*/
Dog.prototype = {
paws : 4,
hair : true
};
/*事实证明,这会使原有对象不能访问原型的新增属性,他们依然通过那个神秘的链接与原有的原型对象保持联系*/
console.log(typeof benji.paws); //undefined
console.log(benji.say()); //Woof
console.log(typeof benji.__proto__.say); //function
console.log(typeof benji.__proto__.paws); //undefined
/*而我们之后创建的所有对象使用的都是被更新后的prototype对象.*/
var lucy = new Dog();
// console.log(lucy.say());//Uncaught TypeError: lucy.say is not a function
console.log(lucy.paws); //4
/*并且,其秘密链接_proto_也指向了新的prototype对象;*/
console.log(typeof lucy.__proto__.say); //undefined
console.log(typeof lucy.__proto__.paws); //number
/*但这时候,新对象的constructor属性就不能保持正确了,原本原本应该是Dog();的引用只想了Object.*/
console.log(lucy.constructor); //function Object() { [native code] }
console.log(benji.constructor);/*
Dog() {
this.tail = true;
}
*/
/*当然,我们可以通过重新设置constructor属性来解决上述所有的异常行为*/
function Dog(){}
Dog.prototype = {};
console.log(new Dog().constructor ===Dog);//false
Dog.prototype.constructor = Dog;
console.log(new Dog().constructor === Dog);//true
/*
* 声明:
* 本文借鉴JavaScript面向对象编程指南(第二版)
* */
原型陷阱
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。