JavaScript 系列之類型(二)

這是我參與8月更文挑戰的第2天,活動詳情查看:8月更文挑戰json

3、類型判斷

JavaScript 判斷變量的方式有:數組

  • typeof(variable)
  • variable instanceof Array
  • variable.constructor = Array
  • Object.prototype.toString.call(variable)

3.1 typeof

var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1, 2, 3, 4];
var json = { name: 'jsliang', age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error = new Error();
var nan = NaN;

console.log(
  typeof num, // number
  typeof str, // string
  typeof bool, // boolean
  typeof arr, // object
  typeof json, // object
  typeof func, // function
  typeof und, // undefined
  typeof nul, // object
  typeof date, // object
  typeof reg, // object
  typeof error, // object
  typeof nan, // number
  
  typeof 10n; // bigint
  typeof BigInt(10); // bigint
  typeof Symbol(); // symbol
);
複製代碼

typeof 能區分的:markdown

  • number
  • string
  • boolean
  • undefined
  • symbol

  • function
  • 檢測其餘類型的時候,都返回 object

PS:爲何會出現 type null // object 這種狀況呢?由於在 JS 的最第一版本中,使用的是 32 位系統,爲了性能考慮使用低位存儲了變量的類型信息,000 開頭表明是對象,然而 null 表示爲全零,因此將它錯誤的判斷爲 object 。雖然如今的內部類型判斷代碼已經改變了,可是對於這個 Bug 倒是一直流傳下來。app

3.2 instanceof

用於實例和構造函數的對應。例如判斷一個變量是不是數組,使用 typeof 沒法判斷,但可使用 [1, 2] instanceof Array 來判斷。由於,[1, 2] 是數組,它的構造函數就是 Arrayide

instanceof 判斷原型鏈指向,咱們能夠看一下它的實現原理:函數

image.png

function myInstanceof(left, right) {
  if (typeof left !== 'object' || right === null) {
    return false;
  }
  
  // 得到類型的原型
  let prototype = right.prototype
  // 得到對象的原型
  left = left.__proto__
  // 判斷對象的類型是否等於類型的原型
  while (true) {
    if (left === null)
      return false
    if (prototype === left)
      return true
    left = left.__proto__
  }
}

console.log(myInstanceof([1,2,3], Array)) // true
複製代碼
var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1, 2, 3, 4];
var json = { name: 'jsliang', age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error = new Error();

console.log(
  num instanceof Number, // false
  str instanceof String, // false
  bool instanceof Boolean, // false
  und instanceof Object, // false
  nul instanceof Object, // false
  arr instanceof Array, // true
  json instanceof Object, // true
  func instanceof Function, // true
  date instanceof Date, // true
  reg instanceof RegExp, // true
  error instanceof Error, // true
)
複製代碼

instanceof 能判斷的有:post

  • Array
  • Function
  • Date
  • RegExp
  • Error

3.3 constructor

var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1, 2, 3, 4];
var json = { name: 'jsliang', age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error = new Error();

function Person(){

}
var Tom = new Person();

console.log(
  Tom.constructor === Person, // true
  num.constructor === Number, // true
  str.constructor === String, // true
  bool.constructor === Boolean, // true
  arr.constructor === Array, // true
  json.constructor === Object, // true
  func.constructor === Function, // true
  date.constructor === Date, // true
  reg.constructor === RegExp, // true
  error.constructor === Error // true
);
複製代碼

獲得的全部結果都是 true,除了 undefinednull,其餘類型基本能夠經過 constructor 判斷。性能

不過由於 constructor 的屬性是能夠被修改的,可能致使檢測出的結果不正確。ui

3.4 Object.prototype.toString.call

var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1, 2, 3, 4];
var json = { name: 'jsliang', age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error = new Error();

console.log(
  Object.prototype.toString.call(num), // [object Number]
  Object.prototype.toString.call(str), // [object String]
  Object.prototype.toString.call(bool), // [object Boolean]
  Object.prototype.toString.call(arr), // [object Array]
  Object.prototype.toString.call(json), // [object Object]
  Object.prototype.toString.call(func), // [object Function]
  Object.prototype.toString.call(und), // [object Undefined]
  Object.prototype.toString.call(nul), // [object Null]
  Object.prototype.toString.call(date), // [object Date]
  Object.prototype.toString.call(reg), // [object RegExp]
  Object.prototype.toString.call(error), // [object Error]
);
複製代碼

一個完美的判斷方法,能夠檢測上面提到的全部類型,只須要將它的結果 result.slice(8, -1) 就能獲得具體的類型。this

相關文章
相關標籤/搜索