首頁  >  文章  >  web前端  >  JavaScript專題之六:型別檢測

JavaScript專題之六:型別檢測

coldplay.xixi
coldplay.xixi轉載
2021-03-09 09:47:062245瀏覽

JavaScript專題之資料類型偵測的那些事

JavaScript專題之六:型別檢測

目錄

  • 一、typeof
  • 二、instanceof
  • 三、constructor
  • 四、stringTag是什麼?
  • 五、實作幾個資料偵測的方法
  • 寫在最後

(免費學習推薦: javascript影片教學

#前言

在《JavaScript的資料類型》中我們也提到過簡單的類型檢測問題。

身為前端的同學,我們應該都知道可以使用typeof和instanceof在執行時判斷JavaScript資料的類型,那麼他們都是怎麼判斷的呢?一千個人會不會寫出來一千個判斷方法?

本文會從通用的typeof、到專攻物件的instanceof,再到isNull、isNumber、isString等方法,討論如何判斷資料類型,一起加油~

JavaScript專題之六:型別檢測

一、typeof

typeof:運算子傳回字串,表示未經計算的運算元的型別。

我們都知道,在ES6 前,JavaScript 共六種資料類型,分別是:

  1. Undefined
  2. Null
  3. # Boolean
  4. Number
  5. String
  6. Object

#然而當我們使用typeof 對這些資料類型的值進行操作的時候,傳回的結果但不是一一對應,分別是:

  1. Undefined
  2. object – ***
  3. Boolean
  4. Number

# String

Object

有一些意外,

typeof null => 'object'

typeof function(){} => 'function '

所以在大多數情況下我們可以使用typeof來偵測基本資料類型,但是,偵測得到的Object後,卻無法區分是哪一種Object:

typeof [] === 'object'; //truetypeof {} === 'object'; //truetypeof null === 'object'; //true

總結

在偵測Js的原始型別時,除了

typeof null

傳回
object

之外,其他的都傳回對應類型名的小寫字母。

二、instanceof

我們判斷物件類型的時候,可以使用instanceof:

如果對原型及原型鏈不太熟悉的同學不妨看看這篇文章從原型到原型鏈

定義

instanceof 運算子用於偵測建構函式的prototype 屬性是否出現在某個實例物件的原型鏈上。


實例

const arr = [];const obj = {};console.log(arr instanceof Array);   // trueconsole.log(arr instanceof Object);  // trueconsole.log(obj instanceof Array);   // falseconsole.log(obj instanceof Object);  // true
注意instanceof是能符合類型的父類的,所以arr instanceof Array和arr instanceof Object都是true,因為Object是Array的父類。

滿足class extends原型鏈規則的父子類別關係的物件都能被匹配:

class

class Base {}class Current extends Base {}const obj = new Current();console.log(obj instanceof Current); // trueconsole.log(obj instanceof Base); // true

原型鏈

function Foo() {}function Bar() {}Bar.prototype = new Foo();const obj = new Bar();console.log(obj instanceof Bar); // trueconsole.log(obj instanceof Foo); // true
注意如果我們修改obj的原型鏈能改變instanceof的結果:

function Other() {}obj.__proto__ = new Other();console.log(obj instanceof Other); // trueconsole.log(obj instanceof Foo); // false

#總結

instanceof借助了原型鏈來判斷的實際上,只要一個型別

Type

的prototype在一個物件obj的原型鏈上,那麼

obj instanceof Type

就是true,否則就是false。

三、constructor

有時候我們不希望匹配父類型,只希望匹配當前類型,那麼我們可以用constructor來判斷:
  • 如果對原型及原型鏈不太熟悉的同學不妨看看這篇文章從原型到原型鏈
  • 定義

返回創建實例物件的Object

建構函數的參考。請注意,此屬性的值是對函數本身的引用,而不是一個包含函數名稱的字串。

實例

const arr = [];console.log(arr.constructor === Array); // trueconsole.log(arr.constructor === Object); // false
物件的constructor會傳回它的類型,而類型在定義的時候,會建立一個name只讀屬性,值為類型的名字。
class Foo {}console.log(Foo.name); // Fooconst foo = new Foo();console.log(foo.constructor === Foo); // trueconsole.log(foo.constructor.name === 'Foo'); // true
問題

constructor.name 一定就是正確的嗎?

我們可以修改它嗎?

四、stringTag是什麼? 4.1 stringTag——類型標籤

###如果你看過一些函式庫的早期實現,你會發現使用###Object.prototype.toString###來做型別判斷的方式,他們會資料型別的字串標誌,被稱為###stringTag####;#######4.2 Object.prototype.toString#########定義###################################################################### #######toString()###方法傳回一個表示該物件的字串。 ######每個物件都有一個###toString()### 方法,當該物件被表示為一個文字值時,預設情況下,###toString()### 方法被每個Object 物件繼承。 ###

如果此方法在自定义对象中未被覆盖,toString() 返回 “[object type]”,其中 type 是对象的类型。以下代码说明了这一点:

实例

比如这是requirejs里面的代码片段。

var ostring = Object.prototype.toString;function isArray(it) {
  return ostring.call(it) === '[object Array]';}

toString时都做了什么?

这里直接将冴羽大大的总结搬了过来:

When the toString method is called, the following steps are taken:

  1. If the this value is undefined, return “[object Undefined]”.
  2. If the this value is null, return “[object Null]”.
  3. Let O be the result of calling ToObject passing the this value as the argument.
  4. Let class be the value of the [[Class]] internal property of O.
  5. Return the String value that is the result of concatenating the three Strings "[object ", class, and “]”.

当 toString 方法被调用的时候,下面的步骤会被执行:

  1. 如果 this 值是 undefined,就返回 [object Undefined]
  2. 如果 this 的值是 null,就返回 [object Null]
  3. 让 O 成为 ToObject(this) 的结果
  4. 让 class 成为 O 的内部属性 [[Class]] 的值
  5. 最后返回由 "[object " 和 class 和 “]” 三个部分组成的字符串

注意

有几点我们需要注意:

  • toString无法区分原始类型及其构造对象;
    • 我们认为Number、Boolean这种类型在被构造器构造出来后的类型应该是对象
    • 但toString都会返回[object number]等原始类型;
  • toString方法是可以自定义的;

JavaScript專題之六:型別檢測

五、实现几个数据检测的方法

好了看了几款常用的类型判断方法后,我们可不可以实现自己的类型判断工具?就利用上述提到的一个或多个方法。我们自己动手丰衣足食~

5.1 isObject

注意,我们认为null不是一个对象,它就是null~

function isObject(value) {
    const type = typeof value;
    return value != null && (type === 'object' || type === 'function');}
5.2 isNull
function isNull(value) {
    return value === null;}
5.3 isFunction
function isFunction(value) {
    return typeof value === 'function';}
5.4 isArray
var isArray = Array.isArray || function( value ) {
    return type(value) === "array";}
5.5 stringTag
const toString = Object.prototype.toString;function getTag(value) {
    // if (value === null) return '[object Null]';
    // if (value == null) return '[object Undefined]'
    if (value == null) {
        return value === undefined ? '[object Undefined]' : '[object Null]'
    }
    return toString.call(value)}

好了到最后,大家平时对类型检测的态度是什么样的呢?

相关免费学习推荐:javascript(视频)

以上是JavaScript專題之六:型別檢測的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除