深入 JavaScript(6) - 一静一动

这里是JavaScript核心的内容了. 挺多的JavaScript测试题也是围绕这个出的.
这里的一静一动指的是:
  • 静, 词法作用域 - Lexical scoping
  • 动, 动态绑定this的值
一、静
在JavaScript中函数有静态的词法作用域. 这是什么意思?
当我们写好了代码, 如 lexical.js , 那么此刻, 代码里的各个函数的作用域就已经确定了. 与这个函数是否被调用, 在哪儿调用, 被谁调用无关.
作用域大都被说成作用域链, 它是有层级关系的, 从顶层向底层直到全局作用域; 或者说从链头部向尾部延伸, 直到最后面的全局空间Global.
Global总在最后.
此作用域是函数的一个内部属性, 代码访问不到. 技术书籍中通常用 [[scope]] 这个名字来表示这个静态的词法作用域.
 
静 和 作用域 都说了, 那么这个词法是什么?
JavaScript解释器只需要分析源代码的文本就能确定[[scope]]. 嗯..我是这么理解的
 
例:
(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
var scope = "global";
function foo() {
  console.log(scope);
}
function bar() {
  var scope = "local";
  foo();
  console.log(scope);
}
 
bar();
// global
// local
(2)
 
1
2
3
4
5
6
7
8
9
10
var scope = "global",
  ns = {
    scope: "In object",
    bar: function() {
      console.log(scope); // !this.scope
    }
  };
 
ns.bar();
//result global

 (3)

1
2
3
4
5
6
7
8
9
10
11
var scope = "global",
  bar = function() {
    var scope = "In bar";
 
    return function() {
      // var scope = "In anony fn";
      console.log(scope);
    };
  };
 
bar()();

 

======
稍微讲下, 这里形成了闭包, 比上面的例子稍复杂些, 但是判断词法作用域却非常简单! 为什么, 因为我们不用去考虑什么闭包什么调用逻辑,
我们只要分析代码文本就行了!
例子里一共出现2个函数, 3个scope变量(算上我注释掉的). 前提我们知道JavaScript中函数能产生新的作用域.
那么, 我们看一下return的这个匿名函数的词法作用域 [[scope]] 是什么?
分析代码文本, 首先有匿名函数自己, 往下是包着它的 bar 函数, 再往下发现没有函数了, 那就到Global了.
[[scope]] = Returned anonymous function -> bar function -> global
当我们确定了[[scope]], 当解析标识符scope的时候就是从这个链的顶端 anonymous function 向底部 Global 查找;
 
那么就上面的例子, bar()()调用时, 我们相当于在Global空间里调用了bar函数返回的匿名函数, 此函数打印 console.log(scope). 虽说是在Global里打印scope, 但是结果
是"In bar". 因为无论在哪调用, [[scope]]早已经确定! [[scope]] = Returned anonymous function -> bar function -> global
当打印scope的时候, 从Returned anonymous function开找, 发现没有 scope(被我注释掉了), 找下一个, bar function 发现目标, 打印之.
 
 

深入 JavaScript(6) - 一静一动,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。