1. typeof null === 'object'
不同的物件在底層都表示為二進位制,在Javascript中二進位制前三位都為0的話會被判斷為Object型別,null的二進位制表示全為0,自然前三位也是0,所以執行typeof時會返回"object"。
2. 陣列的字串鍵值如果可以轉換成十進位制陣列,那麼就會變成陣列的下標。
例子:
3. 函式是可以呼叫的物件
函式可以像任何其他物件一樣具有屬性和方法。它們與其他物件的區別在於函式可以被呼叫,函式的length屬性時函式形參的數量。
例子:
4. 類陣列物件
類陣列物件具有length屬性,也可以通過[下標]
這種方法獲取對應的值,但是它無法使用陣列的push,forEach,indexOf等方法,並不是真正的陣列。
例子:
可以通過以下兩種方法將類陣列物件變為陣列:
- Array.prototype.slice.call(類陣列物件)
- Array.from(類陣列物件)
例子:
5. 0.1 + 0.2 !== 0.3
JavaScript中數字型別基於IEEE 754標準實現,該標準通常被稱為“浮點數”,JavaScript使用的是雙精度格式(64位二進位制),二進位制浮點數的問題就是:
0.1 + 0.2 !== 0.3;
在二進位制浮點數中 0.1 + 0.2 = 0.30000000000000004
可以通過設定一個誤差範圍來判斷0.1 + 0.2和0.3是否相等。這個誤差範圍成為“機器精度”,在JavaScript中,這個值一般是2.220446049250313e-16
,從ES6開始,可以通過Number.EPSILON獲得。
function numbersCloseEnoughEqual(num1, num2) {
return Math.abs(num1 - num2) > Number.EPSILON;
}
let a = 0.1 + 0.2;
let b = 0.3;
numbersCloseEnoughEqual(a, b); // true
複製程式碼
6. Number.MAX_VALUE,Number.MIN_VALUE,Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER
JavaScript中:
- Number.MAX_VALUE,定義了能夠呈現的最大浮點數
- Number.MIN_VALUE,定義了能夠呈現的最小浮點數
- Number.MAX_SAFE_INTEGER,定義了能夠呈現的最大整數
- Number.MIN_SAFE_INTEGER,定義了能夠呈現的最小整數
7. .
運算子
.
運算子需要注意的一點是:因為它是一個有效的數字字元,會被優先認為是數字的一部分,然後才是物件的屬性訪問運算子,這就導致了下面這些情況:
8. null 和 undefined
- null,空值
- undefined,未賦值
可以使用 void 運算子獲得安全的undefined,比如:void 0;
關於安全的undefined,可以看看這篇文章var undefined = 1 這樣賦值有效果嗎?
9. NaN
NaN指的是“不是一個數字”(not a number),但是它卻是數字型別,而且它是自己和自己不相等:
NaN === NaN; // false
typeof NaN; // "number"
複製程式碼
如何檢測一個值是不是NaN:
-
isNaN和Number.isNaN
全域性方法isNaN並不可靠
isNaN('foo'); // true 複製程式碼
foo並不是NaN,而結果卻是true。
所以推薦使用Number.isNaN方法:
Number.isNaN('foo'); // false Number.isNaN(NaN); // true 複製程式碼
Number.isNaN是ES6中新增的,ES6之前可以用下面這種方法檢測:
if(!Number.isNaN) { Number.isNaN = function(value) { var n = parseInt(value); return n !== n; }; } 複製程式碼
10. 基本型別和引用型別
JavaScript中除了物件以外,其他型別都叫基本型別。
它們之間的區別通過一個例子說明:
let obj = {
a: 1
};
let obj1 = obj;
obj1.b = 2;
console.log(obj); {a: 1, b: 2}
console.log(obj1); {a: 1, b: 2}
let str = 1;
let str1 = str;
str1 += 1;
console.log(str); // 1
console.log(str1); // 2
複製程式碼
因為引用型別傳遞的是值的地址,所以obj和obj1中的地址指向的是同一個物件,改變其中一個會影響到另一個。基本型別相當於將原始值賦值了一份給目標值,原始值和目標值是獨立的,相互不會影響。
對於引用型別來說,一個引用無法改變另一個引用的指向。 例子:
let arr = [1,2,3];
let arr1 = arr;
arr1 = [4,5,6];
console.log(arr); // [1,2,3]
console.log(arr1); // [4,5,6]
複製程式碼
所以引用型別的值在拷貝的時候分為淺拷貝和深拷貝,淺拷貝就像例子中的一樣,直接賦值即可,深拷貝可以使用JSON.parse(JSON.stringify(obj))
實現。