@
-------------人工分割線-------------
typeof
MDN:typeof操作符返回一個字串,表示未經計算的運算元的型別。
let data = {
number : 1,
string : 'b',
boolean : true,
symbol : Symbol(),
null : null,
undefined : undefined,
nan : NaN,
function : function (){},
object : {},
array: [],
};
for(let key in data) {
console.log(key + ':::', typeof data[key]);
}
// ----------- 列印結果 ------------------
number::: number
string::: string
boolean::: boolean
symbol::: symbol
null::: object // 需要注意
undefined::: undefined
nan::: number // 需要注意
function::: function
object::: object
array::: object // 需要注意
null、array:列印結果都是object
NaN:列印結果是number
關於null列印成object的原因:屬於JS遺留bug,在一開是的JS版本種使用32位系統,為了提高效能使用低位儲存變數的型別資訊,所以將000 開頭代表是物件,但是 null 表示為全零,所在在判斷null時也會將它錯誤的判斷為 object 。
instanceof
MDN:instanceof 運算子用來檢測 constructor.prototype 是否存在於引數 object 的原型鏈上
function Animal(name) {
this.name = name;
}
let cat = new Animal('cat');
let dog = new Animal('dog');
console.log(cat instanceof Animal);
console.log(cat instanceof dog); // 報錯:Right-hand side of 'instanceof' is not callable
instanceof的右邊要求是一個建構函式,否則報錯。
如何理解:instanceof 運算子用來檢測 constructor.prototype 是否存在於引數 object 的原型鏈上??:
::: 如:cat instanceof Animal:Animal.prototype是否在cat的原型鏈上【Animal--Object】,顯然是在的,所以返回true。
思考:
function Animal(name) {
this.name = name;
}
let cat = new Animal('cat'); //
// 此時將Animal.prototype指向空物件
let A = {};
Animal.prototype = A;
let cat2 = new Animal('cat2');
console.log(cat instanceof Animal);
console.log(cat2 instanceof Animal);
此時應該列印什麼?
先分析cat的原型鏈:【Animal -- Object】
cat2的原型鏈:【A --- Object】
此時Animal.prototype指向A物件,所以A在cat2的原型鏈上,而不在cat上。
總結:先找到Animal.prototype,在列出cat的原型鏈,如果在就true否則false。
特殊點:
1:instanceof 和多全域性物件(例如:多個 frame 或多個 window 之間的互動)
不同的全域性環境擁有不同的全域性物件,從而擁有不同的內建型別建構函式。這可能會引發一些問題。比如,表示式 [] instanceof window.frames[0].Array 會返回 false,因為 Array.prototype !== window.frames[0].Array.prototype,並且陣列從前者繼承。
2: String 物件和 Date 物件都屬於 Object 型別和一些特殊情況
let simpleStr = 'simpleStr';
let myObj = {};
let myNullObj = Object.create(null);
console.log(simpleStr instanceof String); //false [檢查原型鏈會找到 undefined]
console.log(myObj instanceof Object); //true
console.log(myNullObj instanceof Object); //false [一種建立非 Object 例項的物件的方法]
Object.prototype.toString
MDN:方法返回一個表示該物件的字串。
// 資料來源看開頭的程式碼
for(let key in data) {
console.log(key + ':::', Object.prototype.toString.call(data[key]));
}
/*
number::: [object Number]
string::: [object String]
boolean::: [object Boolean]
symbol::: [object Symbol]
null::: [object Null]
undefined::: [object Undefined]
nan::: [object Number] // 需要注意
function::: [object Function]
object::: [object Object]
array::: [object Array]
* */
-
為了每個物件都能通過 Object.prototype.toString() 來檢測,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式來呼叫,傳遞要檢查的物件作為第一個引數,稱為 thisArg。
-
Object.prototype.toString 的原理是當呼叫的時候, 就取值內部的 [[Class]] 屬性值, 然後拼接成 '[object ' + [[Class]] + ']' 這樣的字串並返回. 然後我們使用 call 方法來獲取任何值的資料型別.
isArray
MDN:如果物件是 Array ,則返回true,否則為false。
這個比較簡單不寫例子了。
特殊性:當檢測Array例項時, Array.isArray 優於 instanceof,因為Array.isArray能檢測iframes.
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]
// Correctly checking for Array
Array.isArray(arr); // true
// Considered harmful, because doesn't work though iframes
arr instanceof Array; // fals
iisNaN
MDN:用來確定一個值是否為NaN 。注:isNaN函式內包含一些非常有趣的規則;你也可以使用 ECMAScript 2015 中定義的 Number.isNaN() 來判斷。與 JavaScript 中其他的值不同,NaN不能通過相等操作符(== 和 ===)來判斷 ,因為 NaN == NaN 和 NaN === NaN 都會返回 false。 因此,isNaN 就很有必要了。
isNaN(NaN); // true
isNaN(undefined); // true
isNaN({}); // true
isNaN(true); // false
isNaN(null); // false
isNaN(37); // false
// strings
isNaN("37"); // false: 可以被轉換成數值37
isNaN("37.37"); // false: 可以被轉換成數值37.37
isNaN("37,5"); // true
isNaN('123ABC'); // true: parseInt("123ABC")的結果是 123, 但是Number("123ABC")結果是 NaN
isNaN(""); // false: 空字串被轉換成0
isNaN(" "); // false: 包含空格的字串被轉換成0
// dates
isNaN(new Date()); // false
isNaN(new Date().toString()); // true
isNaN("blabla") // true: "blabla"不能轉換成數值
// 轉換成數值失敗, 返回NaN
一個有用的特性:
有許多方式來看待isNaN():如果isNaN(x)返回false,那麼x在任何算數表示式中都不會使表示式等於NaN;如果返回true,x會使所有算數表示式返回NaN。這就意味著,在JavaScript中,isNaN(x)==true等價於x-0=NaN(在JavaScript中 x-0 == NaN 總是返回false,所以你不用去測試它)。
實際上, isNaN(x), isNaN(x - 0),isNaN(Number(x)), Number.isNaN(x - 0),和Number.isNaN(Number(x)) 的返回值都是一樣的 並且在JavaScript中isNaN(x)是這些表示式中最短的表達。