js易犯錯誤與易混淆的重要知識點

2022-11-24 19:06:45 字數 1094 閱讀 4646

一:作用域的問題

簡單案例1:

var a = 1;

var n = function ()

n(); =》輸出undefined

原因:這是因為js中,在一個函式內引用變數時,會現在其當前函式內部作用域搜尋,也被稱為函式內部作用域。當其內部沒有該變數時,則搜尋其上層作用域,一直到全域性作用域。該例子中 a 先搜尋其內部,有a變數的宣告,所以外部的a=1被遮蔽了,至於為什麼a為undefined是因為變數宣告會提前。而a被賦值

的步驟在console.log()之後。

案例2:

var scope='top';

var fnc1 = function ()

fnc1(); =>top

var fnc2 = function ()

fnc2(); =》輸出top

原因:這是因為js是一個靜態的作用域。函式的作用域的巢狀關係是由定義時決定的,並不是由呼叫時決定的。也可以把js看成一種詞法作用域,就是說 不用等到函式載入就已經確定了作用域的巢狀關係。可以直接分析其語法。

二:閉包

閉包的嚴格定義是:‘由函式(環境)及其封閉的自由變數組成的集合體 ’ 通俗的說,js中每個函式都是閉包。

案例:

var p = function () 

return get

}var k1 = p();

var k2 = p();

console.log(k1()); 輸出1

console.log(k1()); 輸出2

console.log(k2());輸出1

console.log(k2()); 輸出2

原因:1:先分析下閉包:var k1=p();該步輸出的是函式get 也就是下面的函式:

function ()

所以:需要再次執行k1,即k1();才能輸出i

2:閉包是一種互不干擾的函式封裝 生成的例項也是互不干擾。首先例項k1/k2在其未被呼叫的時候(k1()/k2())內部的i變數值是0(類似上個案例,函式的作用域的巢狀),當執行一次k1/k2時,變數i就會加1;所以就是上面的輸出答案。