JavaScript學習筆記 - 值的型別的一些知識點

MADAO是不會開花的發表於2018-09-17

1. typeof null === 'object'

不同的物件在底層都表示為二進位制,在Javascript中二進位制前三位都為0的話會被判斷為Object型別,null的二進位制表示全為0,自然前三位也是0,所以執行typeof時會返回"object"。

2. 陣列的字串鍵值如果可以轉換成十進位制陣列,那麼就會變成陣列的下標。

例子:

JavaScript學習筆記 - 值的型別的一些知識點

3. 函式是可以呼叫的物件

函式可以像任何其他物件一樣具有屬性和方法。它們與其他物件的區別在於函式可以被呼叫,函式的length屬性時函式形參的數量。

例子:

JavaScript學習筆記 - 值的型別的一些知識點

4. 類陣列物件

類陣列物件具有length屬性,也可以通過[下標]這種方法獲取對應的值,但是它無法使用陣列的push,forEach,indexOf等方法,並不是真正的陣列。

例子:

JavaScript學習筆記 - 值的型別的一些知識點

可以通過以下兩種方法將類陣列物件變為陣列:

  1. Array.prototype.slice.call(類陣列物件)
  2. Array.from(類陣列物件)

例子:

JavaScript學習筆記 - 值的型別的一些知識點

JavaScript學習筆記 - 值的型別的一些知識點

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,定義了能夠呈現的最小整數

JavaScript學習筆記 - 值的型別的一些知識點

7. .運算子

.運算子需要注意的一點是:因為它是一個有效的數字字元,會被優先認為是數字的一部分,然後才是物件的屬性訪問運算子,這就導致了下面這些情況:

JavaScript學習筆記 - 值的型別的一些知識點

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))實現。

相關文章