为啥 JSHint 反对位运算符?我应该如何表达这个代码?

Posted

技术标签:

【中文标题】为啥 JSHint 反对位运算符?我应该如何表达这个代码?【英文标题】:Why does JSHint argue against bitwise operators? How should I express this code?为什么 JSHint 反对位运算符?我应该如何表达这个代码? 【发布时间】:2012-07-21 05:57:35 【问题描述】:

我正在使用这段 javascript 来生成 UID:

(原文:)

//If ID has not been defined then generate a new unique ID.
if(!id)
    id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c)  var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); );

(格式化以便可以阅读:)

// If ID has not been defined then generate a new unique ID.
if (!id) 
    id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
        /[xy]/g, 
        function (c)  
            var r = Math.random() * 16 | 0, 
                v = c == 'x' ? r : (r & 0x3 | 0x8); 
            return v.toString(16); 
        
    );

JSHint 不喜欢使用按位 OR 和 AND 运算符。我想知道如何将其重写为更“标准友好”。

编辑:JSHint 状态:

Line 8: id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c)  var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); );
Unexpected use of '|'.

Line 8: id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c)  var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); );
Expected '===' and instead saw '=='.

Line 8: id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c)  var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); );
Unexpected use of '&'.

Line 8: id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c)  var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); );
Unexpected use of '|'.

【问题讨论】:

除了“我不喜欢它”之外是否还显示任何消息? PS:使用位运算符处理位是一种标准且友好的方式 我在提供的消息中添加了。 【参考方案1】:

关于“为什么反对按位运算符”。我喜欢这个来自TSLint docs

按位运算符通常是拼写错误 (...) 它们也可能表明代码过于聪明,会降低可维护性。

【讨论】:

【参考方案2】:

根据JSHint docs,是因为

“位运算符在 JavaScript 程序中非常少见”

正如其他人所提到的,您可以禁用 bitwise JSHint 选项来消除警告。

【讨论】:

回答问题的唯一答案,应该被接受。但是 JSHint(和 TSLint)标记按位操作的原因实际上很愚蠢。位运算符有一些适当但罕见的使用场景,对于这些场景,除了位运算符之外,您永远不应该使用任何东西。【参考方案3】:

这对我来说很好用:

return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
    function(c: string) 
        var r = Math.floor(Math.random() * 16), 
            v = c === 'x' ? r : (r % 4 + 4);
        return v.toString(16);          
    ).toUpperCase();

【讨论】:

【参考方案4】:

/*jshint bitwise: false*/

在文件的顶部

可用选项列表:http://jshint.com/docs/options/

【讨论】:

不回答为什么的问题。 @Snekse:显然是因为位运算符在 JS 中非常少见,而且很可能用户将 &&& 混淆了 @zerkms,我正在使用 VS2012,这似乎不起作用。错误仍然出现。 @series0ne:然后再问一个问题,详细解释你所拥有的和所经历的。 您也可以通过将其包裹在您的语句中来在本地禁用它:/*jshint bitwise: false*/ your statement /*jshint bitwise: true*/【参考方案5】:

您在一行中塞进了这么多代码(为什么??),以至于您不知道 jshint 向您指出了什么。我重新格式化了代码,我看到了这个:

var r = Math.random() * 16 | 0, 

| 0 在那里做什么?这是一个不必要的无操作。更新:似乎是一种 int-ify 浮点数的方法。

Jshint 似乎不喜欢其他东西,但至少摆脱这个。并将您的代码展开,以便您(和其他人)可以阅读。

【讨论】:

我只是使用这里提供的第二个解决方案:***.com/questions/105034/… 在这个解决方案中存在 200 多票的感知无操作。真的什么都不做吗?编辑:是的,按位或肯定会做一些事情。 ***.com/questions/7487977/… 废话,这可能是一种奇怪的 Javascript 方式,截断为 int。 我认为应该重写代码以使用Math.round()。这会产生开销,但会更清楚正在发生的事情。 @SeanAnderson - 它是截断的,所以Math.floor 更适合作为替代品。与Math.floor 相比,按位或也非常快。 JSHint / JSLint 警告它的原因是因为它们经常是拼写错误,而不是故意的。 @SeanAnderson - 您会注意到 jslint / jshint 不会警告按位移位,因此您不应避免使用按位运算符。但是,尽量不要对您的代码太聪明,这将成为维护的噩梦。如果你有更清晰的表达方式,例如Math.floor() 在这种情况下,请改用它。避免过早的优化。

以上是关于为啥 JSHint 反对位运算符?我应该如何表达这个代码?的主要内容,如果未能解决你的问题,请参考以下文章

jsHint 配置参数小结

为啥加号运算符在 JavaScript 的正则表达式中不起作用? [复制]

正则表达式不匹配,不知道为啥[重复]

你知道应该如何学会正则表达式吗?

为啥下面的表达式返回 true?

HPCC-ECL 逻辑运算符 - 为啥 OR 不短路?