前言
本文是我學習JavaScript過程中收集與整理的一些易錯知識點,將分別從變數作用域,類型比較,this指向,函數參數,閉包問題及物件拷貝與賦值這6個面向進行由淺入深的介紹與講解,其中也涉及了一些ES6的知識點。
JavaScript知識點
1.變數作用域
var a = 1; function test() { var a = 2; console.log(a); // 2 } test();
上方的函數作用域中宣告並賦值了a,且在console之上,所以遵循就近原則輸出a等於2。
var a = 1; function test2() { console.log(a); // undefined var a = 2; } test2();
上方的函數作用域中雖然宣告並賦值了a,但位於console之下,a變數被提升,輸出時已宣告但尚未被賦值,所以輸出undefined。
var a = 1; function test3() { console.log(a); // 1 a = 2; } test3();
上方的函數作用域中a被重新賦值,未被重新聲明,且位於console之下,所以輸出全域作用域中的a。
let b = 1; function test4() { console.log(b); // b is not defined let b = 2; } test4();
上方函數作用域中使用了ES6的let重新宣告了變數b,而let不同於var其不存在變數提升的功能,所以輸出錯誤b is not defined。
function test5() { let a = 1; { let a = 2; } console.log(a); // 1 } test5();
上方的函數作用域中用let宣告了a為1,並在區塊級作用域中宣告了a為2,因為console並不在函數內的區塊級作用域中,所以輸出1 。
2.型別比較
var arr = [], arr2 = [1]; console.log(arr === arr2); // false
上方兩個不同的陣列比較,console為false。
var arr = [], arr2 = []; console.log(arr === arr2); // false
上方兩個相同的陣列比較,因為兩個單獨的陣列永遠不相等,所以console為false。
var arr = [], arr2 = {}; console.log(typeof(arr) === typeof(arr2)); // true
上方利用typeof比較數組和對象,因為typeof取得NULL、數組、對象的型別都是object,所以console為true。
var arr = []; console.log(arr instanceof Object); // true console.log(arr instanceof Array); // true
上方利用instanceof判斷一個變數是否屬於某個物件的實例,因為在JavaScript中陣列也是物件的一種,所以兩個console都為true。
3.this指向
var obj = { name: 'xiaoming', getName: function () { return this.name } }; console.log(obj.getName()); // 'xiaoming'
上方物件方法中的this指向物件本身,所以輸出xiaoming。
var obj = { myName: 'xiaoming', getName: function () { return this.myName } }; var nameFn = obj.getName; console.log(nameFn()); // undefined
上方將對像中的方法賦值給了一個變量,此時方法中的this也將不再指向obj對象,從而指向window對象,所以console為undefined。
var obj = { myName: 'xiaoming', getName: function () { return this.myName } }; var obj2 = { myName: 'xiaohua' }; var nameFn = obj.getName; console.log(nameFn.apply(obj2)); // 'xiaohua'
上方同樣將obj對像中的方法賦值給了變數nameFn,但是透過apply方法將this指向了obj2對象,所以最終console為xiaohua。
4.函數參數
function test6() { console.log(Array.prototype.slice.call(arguments)); // [1, 2] } test6(1, 2);
上方利用函數中的arguments類別陣列物件取得傳入函數的參數數組,所以輸出數組[1, 2]。
function test7 () { return function () { console.log(Array.prototype.slice.call(arguments)); // 未执行到此,无输出 } } test7(1, 2);
上方同樣利用arguments取得參數,但因test7(1, 2)未執行return中的函數,所以無輸出。若執行test7(1, 2)(3, 4)則會輸出[3, 4]。
var args = [1, 2]; function test9() { console.log(Array.prototype.slice.call(arguments)); // [1, 2, 3, 4] } Array.prototype.push.call(args, 3, 4); test9(...args);
上方利用Array.prototype.push.call()方法向args數組中插入了3和4,並利用ES6延展操作符(…)將數組展開並傳入test9,所以console為[ 1, 2, 3, 4]。
5.閉包問題
var elem = document.getElementsByTagName('p'); // 如果页面上有5个p for(var i = 0; i < elem.length; i++) { elem[i].onclick = function () { alert(i); // 总是5 }; }
上方是一個很常見閉包問題,點擊任何p彈出的值總是5,因為當你觸發點擊事件的時候i的值早已是5,可以用下面方式解決:
var elem = document.getElementsByTagName('p'); // 如果页面上有5个p for(var i = 0; i < elem.length; i++) { (function (w) { elem[w].onclick = function () { alert(w); // 依次为0,1,2,3,4 }; })(i); }
在綁定點擊事件外部封裝一個立即執行函數,並將i傳入該函數即可。
6.物件拷貝與賦值
var obj = { name: 'xiaoming', age: 23 }; var newObj = obj; newObj.name = 'xiaohua'; console.log(obj.name); // 'xiaohua' console.log(newObj.name); // 'xiaohua'
上方我們將obj物件賦值給了newObj對象,從而改變newObj的name屬性,但是obj物件的name屬性也被竄改,這是因為實際上newObj物件所獲得的只是一個記憶體位址,而不是真正的拷貝,所以obj物件被竄改。
var obj2 = { name: 'xiaoming', age: 23 }; var newObj2 = Object.assign({}, obj2, {color: 'blue'}); newObj2.name = 'xiaohua'; console.log(obj2.name); // 'xiaoming' console.log(newObj2.name); // 'xiaohua' console.log(newObj2.color); // 'blue'
上方利用Object.assign()方法進行物件的深拷貝可以避免來源物件被竄改的可能。因為Object.assign() 方法可以把任意多個的來源物件本身的可枚舉屬性拷貝給目標對象,然後返回目標對象。
var obj3 = { name: 'xiaoming', age: 23 }; var newObj3 = Object.create(obj3); newObj3.name = 'xiaohua'; console.log(obj3.name); // 'xiaoming' console.log(newObj3.name); // 'xiaohua'
我們也可以使用Object.create()方法進行物件的拷貝,Object.create()方法可以建立一個具有指定原型物件和屬性的新物件。
結語
學習JavaScript是一個漫長的過程,不能一蹴而就。希望本文介紹的幾點內容能幫助學習JavaScript的同學更深入的了解並掌握JavaScript的語法,少走彎路。
以上就是JavaScript 易錯知識點整理 詳解的內容,更多相關內容請關注PHP中文網(www.php.cn)!
#

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

WebStorm Mac版
好用的JavaScript開發工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!