2

有什么方法可以可靠地确定 JavaScript 对象是否是外来对象类型,如果是,它的类型是什么?

通过“异国情调”,我的意思是(就这个问题而言)任何无法使用Object.create. 这包括ES2016 规范定义为奇异的所有内容(任何“没有一个或多个基本内部方法的默认行为的对象”)以及由ObjectCreate规范方法创建的具有非空internalSlotsList的任何内容,以及任何类型的宿主对象。

通过“可靠”,我的意思是不会被对象添加/删除属性、使用Object.createObject.setPrototypeOf赋予对象意外原型、修改对象的@@toStringTag 或构造函数的@@hasInstance 所欺骗。这对于需要正确处理任意用户数据的库函数很重要。

(这尤其意味着,instanceofandObject.prototype.isPrototypeOf()没有用。例如:var a = Object.create(Array.prototype)制作一个看起来和闻起来像数组的东西——<code>a instanceof Array === true 并且a.pusha.pop预期工作——但缺乏神奇的行为.length并且是很容易证明它不是一个真正的数组异国情调:Array.isArray(a) === false。)

通过“类型”,我的意思大致是 ECMAScript 5.1 语言规范所指的 [[Class]] - 即,将具有特殊 [[DefineOwnProperty]] 行为的 Array 实例与普通对象分开的质量。

例子

有些情况很简单:

  • 可以使用Array.isArray(a).
  • 可以使用 可靠地检测函数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 的方法仍然有用。

4

1 回答 1

0

但是有什么方法可以检测一个函数是绑定函数、本机函数还是闭包?

不,它们都是简单明了的函数。

通过仔细应用原型对象中的方法,可以可靠地检测到其他一些奇异对象,例如

可以通过调用 Set.prototype.has.apply(s, undefined) 来检测集合,并查看它是否抛出 TypeError。

您可以使用instanceof运算符来测试对象是否是特定函数构造函数的实例(或其原型链上的某个对象)。

var mySet = new Set();
console.log(mySet instanceof Set);
于 2017-09-18T10:10:44.393 回答