How to reliably check an object is an EcmaScript 6 Map/Set?(如何可靠地检查对象是 EcmaScript 6 Map/Set?)
问题描述
我只想检查一个对象是 Map 或 Set 而不是 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/Set 的子类.
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之前的方法来正确可靠地检测数组.有关实现 isArray 的可能陷阱.
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/Set,但这对子类实例不起作用(并且很容易被欺骗)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]] 内部槽.这不是那么容易访问 - 它是内部的.不过,我们可以使用 hack:
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 - 它简单、易懂、高效,适用于大多数合理的情况.或者你马上去鸭子打字,只检查对象是否有 has/get/set/delete/add/delete 方法.
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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何可靠地检查对象是 EcmaScript 6 Map/Set?
- 失败的 Canvas 360 jquery 插件 2022-01-01
- addEventListener 在 IE 11 中不起作用 2022-01-01
- 如何使用 JSON 格式的 jQuery AJAX 从 .cfm 页面输出查 2022-01-01
- 400或500级别的HTTP响应 2022-01-01
- CSS媒体查询(最大高度)不起作用,但为什么? 2022-01-01
- 使用RSelum从网站(报纸档案)中抓取多个网页 2022-09-06
- Css:将嵌套元素定位在父元素边界之外一点 2022-09-07
- Flexslider 箭头未正确显示 2022-01-01
- Fetch API 如何获取响应体? 2022-01-01
- Quasar 2+Apollo:错误:找不到ID为默认的Apollo客户端。如果您在组件设置之外,请使用ProvideApolloClient() 2022-01-01
