前言
大家好,我是林三心,用最通俗易懂的話講最難的知識點是我的座右銘,基礎是進階的前提是我的初心。
首先說明這不是標題黨,是真的,這道題席捲了幾十個群,能回答出來的人是微乎其微,最後連王紅元老師都親自出面解答了這道題。
題目
先來看看這道題長什麼樣吧
var x = 1;
function f(x, y = function () { x = 3; console.log(x); }) {
console.log(x)
var x = 2
y()
console.log(x)
}
f()
console.log(x)
// //1、上面的程式碼輸出的是什麼?
// //2、如果把var x = 2註釋掉,輸出的又是什麼?
// //3、如果把f函式第一個引數x改成xx,輸出的又是什麼?
// //4、如果把f函式第一個引數x設定了預設值為4,輸出的又是什麼?
第一題
其實第一題就已經有很多同學答錯了,可能同學們會得出兩種答案
- 1、
undefined、3、3、1
- 2、
undefined、3、2、3
其實通俗點就是兩種想法
- 1、引數y這個函式裡的
x = 3
改變的是全域性
的x
- 2、引數y這個函式裡的
x = 3
改變的是函式f內部
的x
但其實這兩種想法都是錯的,因為大部分同學只看到了兩個 x
- 1、全域性的
x
- 2、f函式內部的
x
但其實忽視還有另一個 x
- 3、f函式的引數
x
這是解題的關鍵,來看看王紅元老師的講解吧
也就是其實 引數y函式
裡 x = 3
其實改變的是 f函式
的 引數x
,而不是 全域性x
或者 f函式內部x
所以正確的輸出應該是 undefined、3、2、1
var x = 1;
function f(x, y = function () { x = 3; console.log(x); }) {
console.log(x) // 引數x沒有預設值,所以:undefined
var x = 2
y() // 改變的是引數x,且輸出引數x,所以:3
console.log(x) // 輸出的是區域性x,所以:2
}
f()
console.log(x) // 全域性x無影響,所以:1
第二題
第二題就簡單多了,去掉 var x = 2
之後,那 f函式
內部就是有一個 x
,那就是 引數x
,所以 f函式
內部 console.log(x)
都是根據 引數x
實時的值來輸出的
var x = 1;
function f(x, y = function () { x = 3; console.log(x); }) {
console.log(x) // 引數沒有預設值,所以:undefined
// var x = 2
y() // 改變引數x = 3,且輸出引數x,所以:3
console.log(x) // 實時引數x的值,所以:3
}
f()
console.log(x) // 全域性x無影響,所以:1
第三題
第三題,把 引數x
改成了 引數xx
,那麼 引數y函式
的 x = 3
改變的就是 全域性x
,因為 引數x
沒了,又因為就近原則, y函式
裡的 x
就是指向 全域性x
var x = 1;
function f(xx, y = function () { x = 3; console.log(x); }) {
console.log(x) // var變數提升但未賦值,所以:undefined
var x = 2
y() // x = 3改變的是全域性x,且輸出全域性x,所以:3
console.log(x) // x = 3改變的是全域性x,與區域性x無關,所以:2
}
f()
console.log(x) // 全域性x被y函式改變了,所以:3
第四題
第四題,是讓 引數x
預設等於 4
,那其實跟第一題的差別就是 引數x
有無預設值
var x = 1;
function f(x = 4, y = function () { x = 3; console.log(x); }) {
console.log(x) // 引數x預設值,所以:4
var x = 2
y() // 改變的是引數x = 3,且輸出引數x,所以:3
console.log(x) // 輸出的是區域性x,所以:2
}
f()
console.log(x) // 全域性x無影響,所以:1
結語
如果你覺得此文對你有一丁點幫助,點個贊,鼓勵一下林三心哈哈。或者可以加入我的摸魚群,我們一起好好學習啊啊啊啊啊啊啊,我會定時模擬面試,簡歷指導,答疑解惑,我們們互相學習共同進步!!