首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在WeakSet中添加JavaScript时,如何预先检查该值是否会引发异常?

在WeakSet中添加JavaScript时,如何预先检查该值是否会引发异常?
EN

Stack Overflow用户
提问于 2017-09-21 09:23:37
回答 3查看 79关注 0票数 3

考虑一个说明性例子:

代码语言:javascript
复制
function addSafely(weakset, value) {
    if (canBeAddedToWeakSet(value)) {
        weakset.add(value);
    }
} 

那么,在这种情况下,您认为实现canBeAddedToWeakSet函数的简洁和正确的方法是什么呢?表演也是一个很好的选择。

我现在使用以下实现,但我不确定它是否是一个完整的实现(即涵盖所有情况):

代码语言:javascript
复制
function canBeAddedToWeakSet(value) {
    return !!value && (typeof value === 'object' || typeof value === 'function');
}

UPD:,以下是那些对性能感兴趣的人的一些基准测试结果。

EN

回答 3

Stack Overflow用户

发布于 2017-09-21 10:02:32

请参阅ECMAScript 2015 (第6版,ECMA-262) WeakSet.add()

23.4.3.1 WeakSet.prototype.add (值) 采取了以下步骤:

  1. 设S是这个值。
  2. 如果Type(S)不是Object,则抛出TypeError异常。
  3. 如果S没有[WeakSetData]内部插槽,则抛出一个TypeError异常。
  4. 如果Type(value)不是对象,则抛出TypeError异常。
  5. 让条目是S的[WeakSetData]内部槽的值的列表。
  6. 对每一个作为条目元素的e重复,
代码语言:javascript
复制
- If e is not empty and SameValue(e, value) is true, then 
- ​
    - Return S. 

  1. 附加值作为条目的最后一个元素。
  2. 返回S。

正如第4项所述,它检查类型(ECMAScript语言类型) of value is Object是否为Object,因为typeof null也是“object”,因此函数canBeAddedToWeakSet应该是:

代码语言:javascript
复制
function canBeAddedToWeakSet(value) {
    return value !== null && (typeof value === 'object' || typeof value === 'function');
}
票数 2
EN

Stack Overflow用户

发布于 2017-09-21 10:20:40

根据ECMAScript规范表35,12.5.5.1节,允许typeof操作符返回主机对象的依赖于实现的字符串,这些对象是Object类型,尽管在这些情况下鼓励实现返回"object",但它们不需要这样做。

不鼓励实现为非标准的外来对象定义新的typeof结果值。如果可能的话,应该对这些对象使用"object"

有趣的表35的例外document.all。这样的推理证明了故意违反规范的行为:

这种违反的动机是希望与两类遗留内容兼容:一种是使用document.all的存在作为检测遗留用户代理的方法,另一种是只支持那些遗留用户代理,并且使用document.all对象而不首先测试它的存在。

我的建议是验证typeof value不返回保证不满足Type(value) of Object的字符串子集,并可选择地检查document.all是否存在。

代码语言:javascript
复制
function canBeAddedToWeakSet(value) {
  switch (typeof value) {
    case 'undefined':
      return value !== undefined
    case 'boolean':
    case 'number':
    case 'string':
    case 'symbol':
      return false
    case 'object':
      return value !== null
    default:
      return true
  }
}
票数 2
EN

Stack Overflow用户

发布于 2017-09-21 10:55:56

免责声明:这是微观优化。表演是每一种品质的敌人。在某些情况下,需要对其进行排序,但大多数情况下,您应该优先考虑简单性+可读性。

如果你真的需要在插入WeakSet之前检查一下.

WeakSet的规范说只有一个Object可以插入到WeakSet中。因此,问题是:“如何检查一个值是否为Object?”

es6.weak-set.js库中( 巴贝尔-聚脂使用的)实现之后,有一个对_is-object.js的传递引用,该引用检查值是否为对象:

代码语言:javascript
复制
module.exports = function (it) {
    return typeof it === 'object' ? it !== null : typeof it === 'function';
};

因此,请放心,您的canBeAddedToWeakSet几乎和它一样好(尽管我会考虑这个三元优化并将它重命名为isObject)。

更新:您可能还想考虑注释中提到的逻辑优化(65 @Patrick!)。

在插入任何集合之前,您什么时候不应该检查是否正确?

如果您有严格的实时性能要求,您可能需要考虑避免对每个插入进行此检查。如果这是您的案例,下面是您的选择:

1)检查每个插入的

优点:防止调用者处理错误的值。

缺点:进行检查和分支预测的性能成本

2)尝试/捕捉

我会关心的是设置异常处理的开销,需要高性能的函数.

优点:保护调用者不处理错误的值。

缺点:尝试/捕获开销的高性能成本(比if语句更糟糕)

3)让调用方处理错误的值

这种策略是为了减少性能关键功能的责任。对于一些打电话的人来说,这张支票可能完全没有必要。例如,在一个域中,我可能知道我只会拥有对象或空。在这种情况下,调用add(myWeakset, value || {})是我最好的性能选择。

尽管如此,有些域可能需要addSafely的能力,因此公开这两种方法可能是有益的。

优点:调用者可以最大化其域的性能。

缺点:不负责任的来电者的风险和复杂性的增加

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46340150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档