深刻 JavaScript(6) - 一靜一動

這裏是JavaScript核心的內容了. 挺多的JavaScript測試題也是圍繞這個出的.
這裏的一靜一動指的是:
  • 靜, 詞法做用域 - Lexical scoping
  • 動, 動態綁定this的值
1、靜
在JavaScript中函數有靜態的詞法做用域. 這是什麼意思?
當咱們寫好了代碼, 如 lexical.js , 那麼此刻, 代碼裏的各個函數的做用域就已經肯定了. 與這個函數是否被調用, 在哪兒調用, 被誰調用無關.
做用域大都被說成做用域鏈, 它是有層級關係的, 從頂層向底層直到全局做用域; 或者說從鏈頭部向尾部延伸, 直到最後面的全局空間Global.
Global總在最後.
此做用域是函數的一個內部屬性, 代碼訪問不到. 技術書籍中一般用 [[scope]] 這個名字來表示這個靜態的詞法做用域.
 
靜 和 做用域 都說了, 那麼這個詞法是什麼?
JavaScript解釋器只須要分析源代碼的文本就能肯定[[scope]]. 嗯..我是這麼理解的
 
例:
(1)
var scope = "global";
function foo() {
  console.log(scope);
}
function bar() {
  var scope = "local";
  foo();
  console.log(scope);
}

bar();
// global
// local
(2)
 
var scope = "global",
  ns = {
    scope: "In object",
    bar: function() {
      console.log(scope); // !this.scope
    }
  };

ns.bar();
//result global

 (3)javascript

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 發現目標, 打印之.
 
 
相關文章
相關標籤/搜索