簡體   English   中英

如何可靠地檢測JavaScript中的外來對象?

[英]How to reliably detect exotic objects in JavaScript?

是否有任何方法可以可靠地確定JavaScript對象是否為奇異對象類型,如果是,則其類型是什么?

“異國”是指(出於該問題的目的)無法使用Object.create創建的任何內容。 這包括ES2016規范定義為外來的所有內容 (任何“不具有一個或多個基本內部方法默認行為的對象”),以及由ObjectCreate規范方法使用非空的internalSlotsList創建的所有內容 ,以及任何種類的宿主對象。

“可靠”是指不受使用對象的屬性添加/刪除,使用Object.createObject.setPrototypeOf為對象提供意外原型,修改對象的@@ toStringTag或構造函數的@@ hasInstance的欺騙。 這對於需要正確處理任意用戶數據的庫函數很重要。

(特別是,這意味着instanceofObject.prototype.isPrototypeOf() 。例如: var a = Object.create(Array.prototype)產生看起來和聞起來像數組a instanceof Array === truea.pusha.pop可以按預期工作,但是缺少魔術行為.length ,很容易顯示它不是實際的外來數組: Array.isArray(a) === false 。)

“類型”,我大致是指ECMAScript 5.1語言規范所指的[[Class]],即,將Array實例以其特殊的[[DefineOwnProperty]]行為與普通對象分開的特性。

例子

有些情況很簡單:

  • 可以使用Array.isArray(a)可靠地檢測到數組外來對象。
  • 可以使用typeof f === 'function'可靠地檢測typeof f === 'function'
    • 但是,有什么方法可以檢測一個函數是綁定函數,本機函數還是閉包?
  • 通過謹慎地應用其原型對象中的方法,可以可靠地檢測到其他一些奇特對象,例如
    • 可以通過調用Set.prototype.has.apply(s, undefined)並查看其是否引發TypeError來檢測集合。

有什么常規方法可以進行這種檢測嗎?

尤其是:

  • 有什么通用的方法可以確定對象是普通對象還是異類對象?
  • 有什么通用的方法可以確定異物的類型?

我注意到Object.toString.apply(o)曾經在此目的上工作得很好:盡管在許多瀏覽器中,它取決於宿主對象的類型,但對於ES 5.1規范中定義的所有類型,它都可以依靠可靠地告訴您該對象是普通的[object Object]還是奇異的[object <Type>] 但是,在ES6和更高版本中,修改@@toStringTag將破壞此測試。

在任何符合JS的實現中都可以使用的檢測方法是理想的,但是特定於Node.js的方法仍然有用。

但是,有什么方法可以檢測一個函數是綁定函數,本機函數還是閉包?

否。它們都是簡單明了的功能。

通過謹慎地應用其原型對象中的方法,可以可靠地檢測到其他一些奇特對象,例如

可以通過調用Set.prototype.has.apply(s,undefined)並查看其是否引發TypeError來檢測集合。

您可以使用instanceof運算符測試對象是否是特定函數構造函數的實例(或其原型鏈中的某個對象)。

var mySet = new Set();
console.log(mySet instanceof Set);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM