搜尋

首頁  >  問答  >  主體

javascript - ES6中函數參數預設值為函數的問題?

我對函數參數預設值為函數的情況有許多困惑
例如

let foo = 'outer';

function bar(func = x => foo) {
  let foo = 'inner';
  console.log(func()); 
}

bar(); //outer

根據阮一峰的es6入門,我知道函數參數是預設值的話,會先有個區塊級作用域包裹參數,初始化結束後區塊級作用域消失

一旦設定了參數的預設值,當函數進行宣告初始化時,參數會形成一個單獨的作用域(context)。等到初始化結束,這個作用域就會消失。這種語法行為,在不設定參數預設值時,是不會出現的。

如果預設值是普通變數我能理解,但還是不懂為什麼這裡輸出的是outer而不是inner

阿神阿神2694 天前1301

全部回覆(4)我來回復

  • 曾经蜡笔没有小新

    曾经蜡笔没有小新2017-07-05 11:11:13

    一句話:函數的閉包在定義時形成,而非運行時。

    回覆
    0
  • 给我你的怀抱

    给我你的怀抱2017-07-05 11:11:13

    把語法糖徹底展開,應該能看清楚點

    let foo = 'outer';
    
    function fk_compiler() {
      return foo;
    }
    
    function bar(func) {
      if (func === undefined) {
        func = fk_compiler;
      }
      let foo = 'inner';
      console.log(func());
    }
    
    bar();

    你看,fk_compiler裡是不是只能回到外部作用域下的foo

    回覆
    0
  • 習慣沉默

    習慣沉默2017-07-05 11:11:13

    js是詞法作用域,foo值取函數定義時的值而不是執行時的值。

    回覆
    0
  • 给我你的怀抱

    给我你的怀抱2017-07-05 11:11:13

    基於回覆者的代碼:

    let foo = 'outer';
    
    function fk_compiler() {
      return foo;
    }
    
    function bar(func) {
      if (func === undefined) {
        func = fk_compiler;
      }
      let foo = 'inner';
      console.log(func());
    }
    
    bar();

    js採取的是詞法作用域,所以,無論函數在哪裡被調用,或者以任何形式被調用,其詞法作用域只由其被聲明時的位置決定。

    fk_compiler被聲明的作用域在全局,所以,它會去訪問全局作用域中的foo。答案也就出來了。

    類似碼:

    function foo(){
      console.log(this.a);
    }
    (function init(){
      var a = 'inner';//此处改为 window.a = 'global';再试试
      foo();
    })();

    回覆
    0
  • 取消回覆