你所不知道的JS — 型別文法 — 值

型別(除了object其餘六種型別又稱 — primitives 基型值):

  • null
  • undefined
  • boolean
  • number
  • string
  • object
  • symbol

typeof 運算子用來檢視值的型別

其中由於 typeof null === "object";  // true
若要檢查一個值是否為null必須透過一個複合條件來檢查
var myVar = null;
(!myVar && typeof myVar === "object"); //true
這裡用利用短路行為來判斷一個值是否為null,由於null為假值(falsy),!myVar將他型別轉換為boolean得到true,才得以繼續執行typeof myVar這個判斷。
var a = 2;
typeof typeof a; // "string"
因為第一個typeof會回傳"number",再對"number"做一次typeof當然會返回string

轉換類陣列:

傳入function的參數arguments就是一個類陣列物件它跟陣列很相似,但不能使用陣列的方法像是 map 和 forEach,因此若我們要使用陣列方法必須將其轉換為真正的陣列。

function myFunc() {
//利用Array.prototype.slice將arguments轉為陣列
//ES6 可利用Array.from(arguments)做轉換
var toArr =[].slice.call(arguments);
toArr.push('一個陣列了');
console.log(toArr);
}
myFunc('我','變成');

將NodeList轉換成陣列:

var NodeList = document.querySelectorAll('div');
var NodeListToArr = Array.apply(null,NodeList);
NodeListToArr.map(function (item) {
console.log(item);
})
//ES6方法
var NodeListES6 = [...document.querySelectorAll('div')];
NodeListES6.map(function (item) {
console.log(item);
})

Number : 在 JavaScript 中,所有以八進位和十六進位表示的數值最後都會被轉換成十進位數值。

var a = 10;      // 10 10進位
var b = 023; // 19 8進位(8進位第一位為0,後面8進位數列範圍為0到7,如果超出了範圍,將忽略前導0,後面的數值當做十進位解析,例如:088會被解析成88。)
var c = 0x12ac; // 4780 16進位(16進位前兩位必須是 0x 或 0X,後面16進位數列0~9、a~f,如果超出了範圍,會顯示SyntaxError)

Number.prototype.toPrecision & Number.prototype.toFixed:

在使用Number方法時必須注意無效語法

ex: 88.toFixed(3);

之所以會無效是因為42.被當做是字面值(literal number)所以沒有.特性運算子存在。

如何使之有效

(88).toFixed(3)
88..toFixed(3) //第一個.被當做number的一部分,第二個.變成特性運算子

如何測試整數

ES6可以用Number.isInteger跟Number.isSafeInteger(安全整數)

ES6以前可用Polyfill
if(!Number.isInteger) {
Number.isInteger = function (Num) {
return typeof Num === "number" && Num % 1 == 0;
};
}

if(!Number.isSafeInteger) {
Number.isSafeInteger = function (Num) {
return Number.isInteger(Num) && Math.abs(Num) < Number.Max_SAFE_INTEGER;
};
}

特殊值:

  • void operator 返回的值永遠是 undefined

ex: void true , void 0, void 1

  • 兩個NaN永遠不相等(永遠不等於自己),可以使用isNaN來檢測NaN,但ES6前的isNaN並沒有先檢查傳入的值是否為number,並且isNaN()在接收到一個值後,會嘗試用Number() 將這個值轉換為數值
var num = 8 / "ok";
var mystring = "ok";
var numString = "88";
var numBool = true; // true 轉為 1、false 轉為 0
var numNull = null; // 轉為 0
console.log(isNaN(num))       // true
console.log(isNaN(mystring)) // true
console.log(isNaN(numString)) // false
console.log(isNaN(numBool)) // false
console.log(isNaN(numNull)) // false

檢測NaN Polyfill:


if(!Number.isNaN) {
Number.isNaN = function (num) {
return (
typeof num === "number" && window.isNaN(num)
);
}
}
var num = 8 / "ok";
var mystring ="ok";
console.log(Number.isNaN(num))      // true
console.log(Number.isNaN(mystring)) // false

建構器:

  • String()
  • Number()
  • Boolean()
  • Array()
  • Object()
  • Function()
  • RegExp()
  • Date()
  • Error()
  • Symbol()

對於用new 建構器產生的東西會是一個object wrapper內包含著primitive,

1. 透過instanceof來確認primitive的型別

2. Object.prototype.toString()印出建構器

3. .valueOf() 取值

var mystring = new String('albert');
typeof mystring; // "object"
mystring instanceof String // true
var myNum = new Number(100); 
typeof myNum; // "object"
myNum instanceof Number // true
Object.prototype.toString.call(myNum)     // "[object Number]"
Object.prototype.toString.call(mystring) // "[object String]"
mystring.valueOf();                       // "albert"
myNum.valueOf(); // 100