函式的引數作用域
阿新 • • 發佈:2019-02-16
注意理解:
1、 var x = 1; function f(x, y = x) { console.log(y); console.log(x);//undefined } f(2) // 2 2、 let x = 1; function f(y = x) { let x = 2; console.log(y); } f() // 1 3、 function f(y = x) { let x = 2; console.log(y); } f() // ReferenceError: x is not defined 4、 var x = 1; function foo(x = x) { // ... } foo() // ReferenceError: x is not defined
一旦設定了引數的預設值,函式進行宣告初始化時,引數會形成一個單獨的作用域,等到初始化完成,這個作用域就會消失,這種語法在不設定預設引數時是不會出現的。
所以:1、在x為新增預設值,y設定預設值為x,這時這個x在外部作用域已經定義,就會將這個值賦值給y,y=1.同理所以2中y=1。3中x在外部函式並沒有被定義,再賦值給y就會報錯。4中,引數的執行順序是從左到右的,所以這句話相當於:let x=x;因此會報錯。
再看一個更加複雜的例子:
var x = 1; function foo(x, y = function() { x = 2; }) { var x = 3; y(); console.log(x); } foo() // 3 x // 1
上面程式碼中,函式foo
的引數形成一個單獨作用域。這個作用域裡面,首先聲明瞭變數x
,然後聲明瞭變數y
,y
的預設值是一個匿名函式。這個匿名函式內部的變數x
,指向同一個作用域的第一個引數x
。函式foo
內部又聲明瞭一個內部變數x
,該變數與第一個引數x
由於不是同一個作用域,所以不是同一個變數,因此執行y
後,內部變數x
和外部全域性變數x
的值都沒變。
變化其中的一小部分:
var x = 1;
function foo(x, y = function() { x = 2; }) {
x = 3;
y();
console.log(x);
}
foo() // 2
x // 1
如果將var x = 3
var
去除,函式foo
的內部變數x
就指向第一個引數x
,與匿名函式內部的x
是一致的,所以最後輸出的就是2
,而外層的全域性變數x
依然不受影響