zoukankan      html  css  js  c++  java
  • 关于原型链和作用域链的终点问题

     1 <script language="javascript" type="text/javascript"> 
     2 function A(){
     3     this.a=11;
     4     this.getA=function(){
     5         return this.a;
     6     }
     7 }
     8 A.prototype.b=33;
     9 Object.prototype.b=22;
    10 var k=new A()
    11 alert(k.b);//33;
    12 </script>            
     1 <script language="javascript" type="text/javascript"> 
     2 function A(){
     3     this.a=11;
     4     this.getA=function(){
     5         return this.a;
     6     }
     7 } 8 Object.prototype.b=22;
     9 var k=new A()
    10 alert(k.b);//22
    11 </script>

      原型链的终点是Object.prototype,当一个访问一个对象的属性的时候,首先在它的构造函数里面去查询this定义的属性,如果找到相应的属性就立即终止查询,如果没有找到相应的属性,就沿着原型链一层一层的查找直到Object.prototype。例如上面的第一个例子访问对象K的属性b,首先查询构造函数下面的this定义的属性,没找到就到原型属性上去找,结果找到了属性b,这是查询终止而不会到Object.prototype;但是对于第二个例子,在构造函数和对象原型中都没找到,就找到了Object.prototype上,这就是原型链的终点,如果在Object.prototype(原型链的终点)上也没有查询到属性的话就会报错undefined。

      注意一个问题就是原型链上面的属性在用for-in loop的时候也会被循环到,所以要过滤掉原型属性的话可以采用

    1 for (var key in obj){
    2   if(obj.hasOwnPropoty(key)){//过滤
    3     console.log(key+':'+obj[key]);
    4   }
    5 }

    或者:

    1 for (var key in obj) {
    2    if (Object.prototype.hasOwnProperty.call(obj, key)) { // 过滤
    3       console.log(key+":"+obj[key]);
    4    }
    5 }
     1 <script language="javascript" type="text/javascript"> 
     2 var c=1;
     3 (function cc(){
     4     var d=2;
     5     console.log(d);//dd输出2
     6     return {
     7         dd : function(){
     8             var e=3;
     9             console.log(e);//dd输出3
    10             console.log(d);//cc输出2
    11             console.log(c);//global输出1
    12         }    
    13     }
    14 })().dd();
    15 <script>

      作用域链的终点是全局对象window,首先来说在一个作用域里面首先访问的是作用域链的最里层,如上面的例子的dd函数里面的e,如果没有找到就沿着作用域链向外层查询,当然和原型链一样查询到了立即终止查询,直到查询到全局window的属性

      作用域链和原型链的联系:

    如果使用with或者catch语句就会改变作用域链。而这些对象都是一些简单对象,他们也会有原型链。这样的话,作用域链会从两个维度来搜寻。

    1、首先在原本的作用域链;

    2、每一个链接点的作用域的链(如果这个链接点是有prototype的话);

     1 Object.prototype.x = 10;
     3 var w = 20;
     4 var y = 30;
     6 // 在SpiderMonkey全局对象里
     7 // 例如,全局上下文的变量对象是从"Object.prototype"继承到的
     8 // 所以我们可以得到“没有声明的全局变量”
     9 // 因为可以从原型链中获取
    10 console.log(x); // 10
    11 (function foo() {
    13   // "foo" 是局部变量
    14   var w = 40;
    15   var x = 100;
    17   // "x" 可以从"Object.prototype"得到,注意值是10哦
    18   // 因为{z: 50}是从它那里继承的
    19   with ({z: 50}) {
    20     console.log(w, x, y , z); // 40, 10, 30, 50
    21   }
    23   // 在"with"对象从作用域链删除之后
    24   // x又可以从foo的上下文中得到了,注意这次值又回到了100哦
    25   // "w" 也是局部变量
    26   console.log(x, w); // 100, 40
    28   // 在浏览器里
    29   // 我们可以通过如下语句来得到全局的w值
    30   console.log(window.w); // 20
    31 })();

     with增大的作用域链:

  • 相关阅读:
    idea 界面乱码问题 file was loaded in the wrong enconding:"utf-8"
    svn 下载,安装,创建库,设置用户和用户组,赋权限
    eclipse文件中的乱码问题
    Eclipse安装Spring插件springsource-tool-suite
    vue.js2.0:搭建开发环境及构建项目
    排序List集合中的元素
    Java GC机制和对象Finalize方法的一点总结
    xfire发布的Webservice中Spring注入为空的解决方案
    Http报文格式学习及Get和Post主要区别总结
    [转] tomcat组成及工作原理
  • 原文地址:https://www.cnblogs.com/cdwp8/p/4060014.html
Copyright © 2011-2022 走看看