JavaSctipt之prototype原型深入分析: prototype的属性是副本,引用,还是固定的查找方式?(3)向实例增加prototype的同名属性

JavaSctipt之prototype原型深入分析: prototype的属性是副本,引用,还是固定的查找方式?
                                      ----03_向实例增加prototype的同名属性


//

  	<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"屏蔽"解除,比较合理!


返回全文

你可能感兴趣的:(function,String,prototype,delete,js引擎)