本篇是對ecmascript 6 入門函式引數預設值一章中的作用域一節的學習總結,並且尋找了一些相關問題,同時還注意到 babel 的乙個轉譯問題。
本節內容參考:
在 ecma-262 中的9.2.12 functiondeclarationinstantiation(func, argumentslist)章節有相關說明。
當解析乙個 js 函式執行上下文的時候,會建立乙個新的environment record
(之後簡稱er
),並且繫結這個er
中每個例項化了的形參(這裡的例項化應該是指在執行函式的時候,形參才能有值,有值之後代表例項化了)。同時在函式體中的每個宣告也被例項化了。
function
fun(arg)
}fun(1); // [function: arg]
複製**
ps:上面幾種情況只是通過表現和結果進行總結,並沒有嚴格按照規範進行分析。如有不對,請不吝賜教。
var x = 20;
function
fun(x = 1
) fun(2);
複製**
按我的理解,既然形參作用域和函式體作用域不共享,那麼函式體作用域(圖中 block)中使用var
宣告的變數為什麼會有乙個初始值,並且和形參例項化的值相同?
希望有前輩可以答疑解惑。有預設值的形參建立的作用域也會沿著作用域鏈查詢變數
function
fun(y = x)
fun(); // referenceerror: x is not defined
複製**
避免暫時性死區(tdz
)
let x = 1;
function
fun(x = x) {}
fun(); // uncaught referenceerror: x is not defined
複製**
let foo = "outer";
function
bar(func = () => foo)
bar(); // outer
複製**
本節內容參考:
在阮一峰老師的 ecmascript 6 入門中,有這樣乙個例子,本身其實是對複雜的形參預設值的展示,但是發現其經過 babel 轉譯後的表現與轉譯前不同。
轉譯成 es5 後([email protected])發現與原來的結果不同了。原因是轉譯後形參和函式體的作用域沒有做隔離
"use strict";
var x = 1;
function
foo(x) ;
var x = 3;
y();
console.log(x);
}foo(); // 2
複製**
基於 babel 基礎上修改
function
foo(x) ;
return
function() .call(this, x, y);
}複製**
也許 babel 出於某些考慮並沒有修改,但是從結果上看,轉譯的**與原來的結果的確不一致了。
其實在分析這個問題的時候,自己還是很吃力,並不能從 ecmascript® 2015 language specification 中分析原因,也就是無法從根本上解釋完整的執行原理。更多的是從其他人的理解中參悟。
這個問題其實在業務場景中很少出現,研究意義大於實用意義。
函式(引數,預設值)
js定義函式引數沒有非常嚴格的要求,可以有也可以沒有,在呼叫的時候也是,引數可以有可以沒有,也可以和定義時的引數個數不一致 沒有給count傳入引數,預設為10 也可以直接在引數中給count賦值 但是特別注意的是不能給count傳入0,因為0與undefined都是false,因此count傳入的...
函式引數預設值
include 函式預設值為0 intmul int x 0 c語言編譯器會報錯,c 不會 intmain int argc,char ar 預設值不需要在定義時給出,宣告時給出即可 intmul int x 函式預設引數的規則 引數的預設值必須從右向左匹配 函式呼叫時使用了預設值,則後續引數必須使...
lua 函式 預設值 定義函式引數的預設值
如果你想要命名引數和預設值,如php或python,你可以使用表構造函式呼叫你的函式 myfunction 函式本身可以有這樣的簽名 function myfunction t setmetatable t,local a,c t 1 or t.a,t 2 or t.b,t 3 or t.c fun...