//
<script type="text/javascript"> var Person = function() { }; Person.prototype.username = new String("zhangsan"); var person = new Person(); alert("实例创建后,person.username: "+person.username); //向实例增加与prototype同名的属性 person.username = new String("lisi"); alert("向实例增加与prototype同名的属性后,person.username: "+person.username); //删除实例上的username属性,然后访问[实例].username得到的会是undefined吗? delete person.username; alert("删除实例上的username属性后,person.username: "+person.username); </script>
//
输出:
实例创建后,person.username: zhangsan
向实例增加与prototype同名的属性后,person.username: lisi
删除实例上的username属性后,person.username: zhangsan
问题: 向实例增加与prototype同名的属性后(person.username = new String("lisi")),然后又删除该属性后,再次访问person.username,为什么得到的不是undefined,而是与原型相同的属性值呢?
假设1副本:
person实例创建时持有原型的属性的副本,然后将实例的username修改为String("lisi"),当删除person.username属性后
又同时向实例增加原型的属性的副本username=new String("zhangsan"),所以再次访问person.username的值也是"zhangsan"..
--删除person的username属性后又向person增加属性值为String("zhangsan")副本的username属性,显然不太可能嘛!
假设2引用:
person实例创建时持有原型的属性的引用,此时Person.prototype.username 和 person.username 都是引用同一个对象String("zhangsan"),person.username = new String("lisi")执行后,person.username引用新的对象 String("lisi"),当删除person.username属性后,又同时将person.username重新引用Person.prototype.username引用的对象String("zhangsan")!
--删除person的username后,又同时向person增加引用String("zhangsan")的username属性,显然不太可能!
假设3固定查找方式:
person实例创建时没有与原型同名的username属性,person.username = new String("lisi")表示向person实例增加与原型同名的username属性,它引用新对象String("lisi"),此时Person.prototype.username引用对象String("zhangsan"),而person.username则引用String("lisi"),此时访问person.username时,因为person自己都有username属性,所以直接输出lisi,当delete person.username后再访问person.username,因为它自身并没有username属性,所以按照固定的 查找方式来查找: 因为person是Person的实例(person instanceof Person 得到的是true),所以查找Person.prototype的属性,如果没找到,继续向上一层原型查找, 在这里,js引擎找到了Person.prototype.username属性,故输出!
--就是当person.username属性存在时,它就会"屏蔽"了原型的username属性,删除person.username后,原型的username"屏蔽"解除,比较合理!
返回全文