JavaScript易錯知識點

JavaScript易錯知識點整理

1.變量作用域

 

上方的函數作用域中聲明並賦值了a,且在console之上,所以遵循就近原則輸出a等於2。

 

上方的函數作用域中雖然聲明並賦值了a,但位於console之下,a變量被提升,輸出時已聲明但尚未被賦值,所以輸出undefined。

 

上方的函數作用域中a被重新賦值,未被重新聲明,且位於console之下,所以輸出全局作用域中的a。

 

上方函數作用域中使用了ES6的let重新聲明瞭變量b,而let不同於var其不存在變量提升的功能,所以輸出報錯b is not defined。

 

上方的函數作用域中用let聲明瞭a爲1,並在塊級作用域中聲明瞭a爲2,因爲console並不在函數內的塊級作用域中,所以輸出1。

2.類型比較

 

上方兩個不同的數組比較,console爲false。

 

上方兩個相同的數組比較,因爲兩個單獨的數組永不相等,所以console爲false。

 

上方利用typeof比較數組和對象,因爲typeof獲取NULL、數組、對象的類型都爲object,所以console爲true。

 

上方利用instanceof判斷一個變量是否屬於某個對象的實例,因爲在JavaScript中數組也是對象的一種,所以兩個console都爲true。

3.this指向

 

上方對象方法中的this指向對象本身,所以輸出xiaoming。

 

上方將對象中的方法賦值給了一個變量,此時方法中的this也將不再指向obj對象,從而指向window對象,所以console爲undefined。

 

上方同樣將obj對象中的方法賦值給了變量nameFn,但是通過apply方法將this指向了obj2對象,所以最終console爲xiaohua。

4.函數參數

 

上方利用函數中的arguments類數組對象獲取傳入函數的參數數組,所以輸出數組[1, 2]。

 

上方同樣利用arguments獲取參數,但因test7(1, 2)未執行return中的函數,所以無輸出。若執行test7(1, 2)(3, 4)則會輸出[3, 4]。

 

上方利用Array.prototype.push.call()方法向args數組中插入了3和4,並利用ES6延展操作符(...)將數組展開並傳入test9,所以console爲[1, 2, 3, 4]。

5.閉包問題

 

上方是一個很常見閉包問題,點擊任何div彈出的值總是5,因爲當你觸發點擊事件的時候i的值早已是5,可以用下面方式解決:

 

在綁定點擊事件外部封裝一個立即執行函數,並將i傳入該函數即可。

6.對象拷貝與賦值

 

上方我們將obj對象賦值給了newObj對象,從而改變newObj的name屬性,但是obj對象的name屬性也被篡改,這是因爲實際上newObj對象獲得的只是一個內存地址,而不是真正的拷貝,所以obj對象被篡改。

 

上方利用Object.assign()方法進行對象的深拷貝可以避免源對象被篡改的可能。因爲Object.assign() 方法可以把任意多個的源對象自身的可枚舉屬性拷貝給目標對象,然後返回目標對象。但是Object.assign() 只是一級屬性複製,比淺拷貝多深拷貝了一層,使用的時候,還要注意這個問題。

 

我們也可以使用Object.create()方法進行對象的拷貝,Object.create()方法可以創建一個具有指定原型對象和屬性的新對象。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章