【问题标题】:Bitshift Operator Used on Object in JavascriptJavascript中对象上使用的位移运算符
【发布时间】:2014-07-11 21:58:00
【问题描述】:

我最近一直在尝试自学 Javascript,我注意到不同作者使用的几个稍微古怪的语法选择。通常我可以弄清楚它们,但是这个让我有点难过。

The author of the post here 创建一个空对象colors,它将包含页面中每种背景颜色的一组属性。每个颜色属性的值都等于该颜色覆盖的总面积。为此,他使用以下语法:

// ...set or override it in the colors object,
// adding the current element area to the
// existing value.
colors[bgColor] = (colors[bgColor] >> 0) + nodeArea;

此时,由 bgColor 的值命名的属性可能存在也可能不存在于对象中。如果这是第一次看到颜色,则括号中表达式的意图可能是返回运行总数或 0。我的问题是,这是否是右移运算符被重载而我正在搜索错误的名称,或者为什么右移操作会这样?

【问题讨论】:

  • 一个更常见的习语是colors[bgColor] || 0
  • 请注意 Barmar 所说的。使用|| 相当普遍。使用>> 并不常见,以至于我几乎从未见过它,而且我阅读了大量源代码。
  • 是的。这看起来像是他在一次混淆代码竞赛中注意到的,并决定在生产代码中使用它只是为了聪明。
  • @Barmar 在调查后。在||>> 之间IS 实际上存在一个有趣的区别。如果 LHS 不是一个数字,它将强制转换为 NaN 并且 0 被传递,所以 ({}) || 0 !== 0({}) || 0 === 0。因此,当它实际适用时,请随意使用它。
  • @GeorgeMauer:我想你的意思是({}) || 0 !== 0(而({}) >> 0 === 0),说得好。我不认为上面代码的作者是这个意思,但它仍然是一个好点。

标签: javascript syntax operators


【解决方案1】:

括号中表达式的意图可能是返回运行总数,如果这是第一次看到颜色,则返回 0。我的问题是,这是否是右移运算符被重载而我正在搜索错误的名称,或者为什么右移操作会这样?

它没有重载(JavaScript 没有运算符重载)。它依赖于undefined >> 00anyNumber >> 0anyNumber 的事实(需要注意)。如果该属性尚不存在,则查找它会产生undefined,因此>> 0 会将其变为0。如果属性 已定义并包含适合 32 位的整数,>> 0 将返回该数字而不更改它。 (如果数字有小数部分,它会被截断,如果它不适合 32 位,如果我没看错,它就是 wrapped,但我认为这不是编码器想要做的。 ) 因此,通过这样做,然后添加区域,它们确实会添加到运行总数中(或者如果还没有,则对其进行初始化)。

它主要是以下的简写版本:

if (colors[bgColor]) {
    colors[bgColor] += nodeArea;
}
else {
    colors[bgColor] = nodeArea;
}

...(因为任何虚假值 >> 00)但具有附加功能,即它始终会导致非NaN 数字提供nodeArea 是非NaN 数字,而对于colors[bgColor](例如{})有一些真实的非数字值,上面的“长”版本将产生一个字符串或NaN

【讨论】:

  • 请注意,由于我在问题评论中指出的细微差别,它实际上更像if(!_.isNumber(colors[bgColor])),其中_.isNumber 取自underscorejs。在绝大多数情况下,这种差异几乎肯定无关紧要
  • @GeorgeMauer:大声笑,我也只是在标记它。很好的评论,谢谢。
【解决方案2】:

这只是避免if 条件的技巧之一。当您使用 bgColor 中的值创建属性时,您可能会这样做

if (colors[bgColor] === undefined) {
    colors[bgColor] = 0;
}
colors[bgColor] += nodeArea;

这是为了确保初始值为0,如果bgColor不在colors中,否则undefined将是该值。因此,为避免这种情况,如果我们可以将undefined 转换为0,我们可以简单地避免if 条件。

console.log(undefined >> 0);
# 0

因此,如果尚未定义 bgColor,则 colors[bgColor] >> 0 将为 0,否则为实际值,因为右移零不会改变实际值。

【讨论】:

  • @T.J.Crowder 你说得对,我只是把它改成了undefined
【解决方案3】:

这可能是尝试将颜色值转换为 32 位值,因为 Javascript 通常将所有值存储为 IIRC 64 位浮点数(精度为 53 位),但在按位运算时,它将它们视为 32 位整数。这可能是试图在添加 NodeArea 之前强制将值视为此类。

我认为它也迫使它被解释为数字,但 NodeArea 的隐式类型通常也会产生这种效果。

编辑 - T.J. Crowder 还提出了我试图从 MDN 中找到但没有找到的另一点:如果属性不存在,则操作的返回值为 0,因此也设置了该值)。面对他的整个帖子,他的观点很好:P。

【讨论】:

  • @T.J.Crowder 是的,我知道我错了:P 现在修复它,ty。
  • (你很善良。:-))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 2020-03-15
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多