变量在原型链中的查找顺序

Posted luckyxcc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了变量在原型链中的查找顺序相关的知识,希望对你有一定的参考价值。

js原型链

下面是一道js题目:
[javascript] view plain copy
  1. function C1(name){  
  2.     if(name){  
  3.         this.name = name;  
  4.     }  
  5. }  
  6.   
  7. function C2(name){  
  8.     this.name = name;  
  9. }  
  10.   
  11. function C3(name){  
  12.     this.name = name || "John";  
  13. }  
  14.   
  15. C1.prototype.name = "Tom";  
  16. C2.prototype.name = "Tom";  
  17. C3.prototype.name = "John";  
  18.   
  19. console.log(new C1().name + "," + new C2().name + "," + new C3().name);  
不运行,求答案!^_^,这道题目对于理解js作用域链十分有用,拿出来和大家分享一下
 
要做出这道题,最重要是理解js中变量在原型链中查找的顺序,
从内到外大致如下:
本地属性 --->  prototype
变量查找顺序:
能在本地属性中找到的绝不去prototype中找
 

1).先来分析第一个

[javascript] view plain copy
  1. new C1().name  
  2.   
  3. function C1(name){  
  4.     if(name){  
  5.         this.name = name;  
  6.     }  
  7. }  
  8.   
  9. C1.prototype.name = "Tom";  
分析:
由于这里没有参数,默认被赋值成了undefined,所以到了if这里就进不去了,因此在C1本地
属性中找不到name这个属性,只能傻逼兮兮的往外找了,又因为C1.prototype.name = "Tom"的
存在,在prototype中找到了name属性,所以最后打印出来的答案是"Tom"

 

2).接着来分析第二个

[javascript] view plain copy
  1. new C2().name  
  2.   
  3. function C2(name){  
  4.     this.name = name;  
  5. }  
  6.   
  7. C2.prototype.name = "Tom";  
分析:
由于这次还是没有参数,同样默认被赋值成了undefined,于是本地属性name被赋值成了
undefined。于是在查找的时候一下子就查到了name的值为undefined,
因此C2.prototype.name = "Tom"并没有什么卵用,最终答案为undefined
 

3).最后来分析第三个

[javascript] view plain copy
  1. new C3().name  
  2.   
  3. function C3(name){  
  4.     this.name = name || "John";  
  5. }  
  6.   
  7. C3.prototype.name = "John";  
分析:
同样是没有参数,undefined作为参数进来以后情况变成了这样:
this.name = undefined || "John",然后结果很明显了本地属性name被赋值成"John"。
接着是从内往外查找,一下子就锁定了本地属性name,此时的值为"John"。
因此C3.prototype.name = "John"同样没有什么用

 
最后的结果:
技术分享图片
 
这里还有道小菜:
[javascript] view plain copy
  1. function Foo() {  
  2.     this.say = function(){  
  3.         alert(‘本地方法‘);  
  4.     }  
  5. }  
  6. Foo.prototype.say = function() {  
  7.     alert(‘prototype方法‘);  
  8. }  
  9. new Foo().say();  
总结:
如果原型链上有相同的方法。那么会优先找本地方法,找到并执行,原型链上的方法就不执行了。
同样的,属性的查找也是这么个顺序。



















以上是关于变量在原型链中的查找顺序的主要内容,如果未能解决你的问题,请参考以下文章

原型和原型链的关系以及查找顺序

js之原型链&继承

JavaScript学习手册(53)

对象类在 DOMWindow 的原型链中出现两次?

JavaScript面向对象(下)

关于JS中原型链中的prototype与_proto_的个人理解与详细总结(代码示例+高清无码大图!——自备瓜子花生)