如何可靠地检查对象是 EcmaScript 6 Map/Set?

How to reliably check an object is an EcmaScript 6 Map/Set?(如何可靠地检查对象是 EcmaScript 6 Map/Set?)
本文介绍了如何可靠地检查对象是 EcmaScript 6 Map/Set?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只想检查一个对象是 MapSet 而不是 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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)