第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

JavaScript 入門教程

typeof

typeof 操作符返回一個字符串,表示未經(jīng)計算的操作數(shù)的類型。(MDN)

typeof 可以用來檢測一個值的類型。

1. 表現(xiàn)

在 ES6 之前,typeof 在瀏覽器的表現(xiàn)是這樣的:

類型 結(jié)果
Boolean “boolean”
String “string”
Number “Number”
Function “function”
undefined “undefined”
null “object”
數(shù)組 “object”
任意對象 “object”
typeof 233; // 輸出:"number"

typeof '嘎?'; // 輸出:"string"

typeof true; // 輸出:"boolean"

typeof undefined; // 輸出:"undefined"

var fn1 = function() {};
function fn2() {};
typeof fn1; // 輸出:"function"
typeof fn2; // 輸出:"function"

typeof null; // 輸出:"object"

typeof []; // 輸出:"object";
typeof ['9', '9', '6']; // 輸出:"object";

typeof {}; // 輸出:"object"

2. 為什么檢查 null 的類型返回 object

這是一個歷史遺留問題,JavaScript 從出現(xiàn)開始都是這個表現(xiàn)。

typeof null; // 輸出:"object"

原因是 null 表示為一個空指針,其內(nèi)部表示類型的標(biāo)簽和對象相同,所以會被設(shè)別為 object

有提案表示想要修復(fù)這個問題,使表現(xiàn)如下:

typeof null; // 輸出:"null"

但這個提案被拒絕了。

3. 為什么檢查數(shù)組類型返回 object

數(shù)組的本質(zhì)是個對象,從數(shù)組的原型上觀察就可以發(fā)現(xiàn)。

圖片描述

同時可以通過 instanceof 檢測數(shù)組的原型鏈上是否有 Object。

Array instanceof Object; // 輸出:true

4. 由基礎(chǔ)對象構(gòu)建的值也返回 object

事實上 typeof 只對字面量敏感。

var num = 1;

typeof num; // 輸出:"number"

如果采用構(gòu)造函數(shù)的形式得到一個值:

var num = new Number(1);

typeof num; // 輸出:"object"

所以除了 Function,構(gòu)造出來的一個值,使用 typeof 檢測類型都會返回 object。

var fn = new Function('console.log("我是特例!")');

typeof fn; // 輸出:"function"

5. 更精準(zhǔn)的檢測類型

使用 Object.prototype.toString.call,可以更精準(zhǔn)的檢測類型。

Object.prototype.toString.call(1); // 輸出: [object Number]
Object.prototype.toString.call(false); // 輸出: [object Boolean]
Object.prototype.toString.call(null); // 輸出: [object Null]
Object.prototype.toString.call([1]); // 輸出: [object Array]
Object.prototype.toString.call({}); // 輸出: [object Object]

通過觀察結(jié)果可以看到,使用這個方式可以區(qū)別出數(shù)組、對象、null這些 typeof 無法區(qū)分的類型。

可是為什么要這樣用呢?不能直接調(diào)用一個值的 toString 嗎?

這涉及到了原型的問題,例如 Number

var number = 996;

console.log(number.__proto__.toString);

number 變量的 toString 方法其實就是 Numberprototype 屬性下的 toString 方法。

var number = 996;

console.log(number.__proto__.toString === Number.prototype.toString);

從這就可以看出進(jìn)行 number.toString() 操作,調(diào)用的就不是 Object.prototype.toString 了。

這兩個 toString 方法的內(nèi)容不同,Number.prototype.toString 做的事情其實就是根據(jù)一些規(guī)則,將值轉(zhuǎn)成字符串,而 Object.prototype.toString 是將對象的一個類型標(biāo)簽進(jìn)行組合輸出。

也就是說大部分?jǐn)?shù)據(jù)類型的原始對象都提供了新的 toString 方法,也就無法調(diào)用到 Object.prototype.toString,所以要用這種方式。

那為什么 Object.prototype.toString 會可以精準(zhǔn)判斷出一個值的類型呢?

這是因為每個值都有一個對應(yīng)的類型標(biāo)簽,在標(biāo)準(zhǔn)中為 [[class]]。

ES6 中,則是使用Symbol.toStringTag作為標(biāo)記。

Object.prototype.toString 在調(diào)用的時候,就會訪問這個標(biāo)記,并返回 [object 標(biāo)記]。

var obj = {
  [Symbol.toStringTag]: '996',
};

Object.prototype.toString.call(obj); // 輸出:"[object 996]"

所有內(nèi)置的類型都具有這個標(biāo)記,所以使用 Object.prototype.toString.call(值) 的方式可以更精準(zhǔn)的獲取到值的類型。

一些舊的數(shù)據(jù)類型的基礎(chǔ)對象為了兼容性,可能訪問不到 Symbol.toStringTag 接口,但是其他許多內(nèi)置對象可以,例如JSON、MathBigInt等:

JSON[Symbol.toStringTag]; // 輸出:"JSON"
Math[Symbol.toStringTag]; // 輸出:"Math"
BigInt.prototype[Symbol.toStringTag]; // 輸出:"BigInt"

6. 小結(jié)

typeof 經(jīng)常被用來檢測基礎(chǔ)類型,但是不夠準(zhǔn)確,無法區(qū)分?jǐn)?shù)組、對象、null,更精準(zhǔn)的檢測應(yīng)考慮使用 Object.prototype.toString 方法。