如何可靠地检查对象是EcmaScript 6 Map / Set? [英] How to reliably check an object is an EcmaScript 6 Map/Set?
问题描述
我只想检查一个对象是一个 Map
或设置
而不是一个 Array
。
I just want to check that an object is a Map
or Set
and not an Array
.
检查数组我使用的是lodash的 _。isArray
。
to check an Array I'm using lodash's _.isArray
.
function myFunc(arg) {
if (_.isArray(arg)) {
// doSomethingWithArray(arg)
}
if (isMap(arg)) {
// doSomethingWithMap(arg)
}
if (isSet(arg)) {
// doSomethingWithSet(arg)
}
}
如果我要实现 isMap
/ isSet
,它需要什么样的?我希望能够抓住 Map
/ 的子类,如果可能,请设置
。
If I were to implement isMap
/isSet
, what does it need to look like? I'd like for it to be able to catch subclasses of Map
/Set
if possible as well.
推荐答案
情况类似于ES5之前正确可靠地检测阵列的方法。请参阅这篇伟大的文章实施的可能陷阱是Array
。
The situation is similar to pre-ES5 methods to detect arrays properly and reliably. See this great article for the possible pitfalls of implementing isArray
.
我们可以使用
-
obj.constructor == Map
/设置
,但不在子类实例上工作(并且很容易被欺骗) -
obj instanceof Map
/Set
,但仍然不能在各个领域工作(并且可以通过原型调整而被欺骗) -
obj [Symbol.toStringTag] ==Map
/Set
,但可以再次被欺骗。
obj.constructor == Map
/Set
, but that doesn't work on subclass instances (and can easily be deceived)obj instanceof Map
/Set
, but that still doesn't work across realms (and can be deceived by prototype mangling)obj[Symbol.toStringTag] == "Map"
/"Set"
, but that can trivially be deceived again.
确实,我们需要测试一个对象是否有一个 [[MapData]]
/ [[SetData ]]
内部插槽。哪个不是很容易访问 - 它是内部的。但是,我们可以使用一个黑客:
To be really sure, we'd need to test whether an object has a [[MapData]]
/[[SetData]]
internal slot. Which is not so easily accessible - it's internal. We can use a hack, though:
function isMap(o) {
try {
Map.prototype.has.call(o); // throws if o is not an object or has no [[MapData]]
return true;
} catch(e) {
return false;
}
}
function isSet(o) {
try {
Set.prototype.has.call(o); // throws if o is not an object or has no [[SetData]]
return true;
} catch(e) {
return false;
}
}
为了常用,我建议 instanceof
- 它是简单,可理解,执行,并适用于大多数合理的情况。或者你马上去打鸭子,只检查对象是否有有
/ get
/ 设置
/ 删除
/ 添加
/ 删除
方法。
For common use, I'd recommend instanceof
- it's simple, understandable, performant, and works for most reasonable cases. Or you go for duck typing right away and only check whether the object has has
/get
/set
/delete
/add
/delete
methods.
这篇关于如何可靠地检查对象是EcmaScript 6 Map / Set?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!