没有操作的JavaScript约定是什么?

kmi*_*las 104 javascript function

没有操作的JavaScript约定是什么?

  • 一个选项只是一个空函数: pass
  • jQuery提供function() {},它只调用上面的空函数.
  • 简单地输入$.noop()或者值是否可以接受false

在上下文中...所有这些工作都没有在Chrome中引发错误:

var a = 2;
(a === 1) ? alert(1) : function() {};
(a === 1) ? alert(1) : $.noop();
(a === 1) ? alert(1) : false;
(a === 1) ? alert(1) : 0;
Run Code Online (Sandbox Code Playgroud)

编辑:很多人回答说,"不要这样做!改变代码结构!" 这让我想起了有人问如何嗅探浏览器的帖子.他接到一连串的帖子说:"不要这样做!它是邪恶的",但没有人告诉他如何嗅探浏览器.这不是代码审查.想象一下,您正在处理无法更改的遗留代码,如果没有传入某些函数,它将丢失一个错误.或者,简单地说,这就是客户想要的方式,他们付钱给我.所以,请尊重,请回答这个问题:在JavaScript中指定"无操作"功能的最佳方法是什么?

编辑2:其中一个怎么样?

true;
false;
0;
1;
null;
Run Code Online (Sandbox Code Playgroud)

Ala*_* S. 88

为了回答原始问题,纯Javascript中的noop函数的最优雅和最简洁的实现(这里也讨论)是Function.prototype.下面的代码段显示了它的用法:

setTimeout(Function.prototype, 10000);
Run Code Online (Sandbox Code Playgroud)

所有三种浏览器(Chrome,Firefox和IE 11)都不会导致解释器在执行上述操作后10秒后返回(您可以使用调试器中的"跳过"模式逐步测试).

虽然这是一个"真正的noop",因为大多数浏览器似乎无法执行以这种方式定义的noop(因此节省了CPU周期),可能会出现一些与此相关的性能问题(正如其他人在评论中或其他答案).

然而,话虽如此,您可以轻松定义自己的noop函数,事实上,许多库和框架也提供noop函数.以下是一些例子:

var noop = function () {};           // Define your own noop in ES3 or ES5
const noop = () => {};               // OR Define your own noop in ES6
setTimeout(noop, 10000);             // Using the predefined noop

setTimeout(function () {} , 10000);  // Using directly in ES3 or ES5
setTimeout(() => {} , 10000);        // Using directly in ES6 as Lambda (arrow function)

setTimeout(angular.noop, 10000);     // Using with angular 1.x
setTimeout(jQuery.noop, 10000);      // Using with jQuery
Run Code Online (Sandbox Code Playgroud)

以下是noop功能(或相关讨论或谷歌搜索)的各种实现的按字母顺序排列的列表:

角1.x中, 角2+(似乎不具有本地实现-用自己的如上图所示),灰烬, jQuery的, Lodash, 的NodeJS, Ramda, 阵营(似乎不具有本地实现-用你自己如上所示), RxJS, 下划线

BOTTOM LINE:虽然Function.prototype是一种在Javascript中表达noop的优雅方式,但是可能存在与其使用相关的一些性能问题.因此,您可以定义和使用自己的(如上所示)或使用您可能在代码中使用的库/框架定义的库.

  • 这应该是答案.如果你不需要超时并希望它立即执行,你甚至可以使用`Function.prototype()`. (5认同)
  • 在ES6中或使用babel或其他的转换程序`(()=> {};)`技术上纯粹的JS,比`function(){}`要短得多,但完全相同. (5认同)
  • 我有兴趣找到一个无操作的构造来有效地关闭程序中的调试代码.在C/C++中,我会使用宏.我测试了将我的fn分配给Function.prototype并对其进行了定时,将结果与函数内部的if语句进行比较,以便立即返回.我还将这些与简单地从循环中完全删除函数的结果进行了比较.不幸的是,Function.prototype表现不佳.调用一个空函数在性能方面要优越得多,甚至比用函数内部简单的'if'测试函数调用函数要快得多. (2认同)

cch*_*ain 55

最简洁,最高效的noop是一个空箭头功能:()=>{}.

除了IE之外,箭头函数在所有浏览器中本机工作(如果必须,还有一个babel变换): MDN


()=>{}Function.Prototype

  • ()=>{}更快的87%Function.prototype在铬67.
  • ()=>{}快25%,Function.prototype在Firefox 60.
  • ()=>{}更快的85%Function.prototype在边缘(2018年6月15日).
  • ()=>{}代码少65%Function.prototype.

下面的测试使用箭头函数加热以产生偏差Function.prototype,但箭头功能是明显的赢家:

const noop = ()=>{};
const noopProto = Function.prototype;

function test (_noop, iterations) {
    const before = performance.now();
    for(let i = 0; i < iterations; i++) _noop();
    const after = performance.now();
    const elapsed = after - before;
    console.info(`${elapsed.toFixed(4)}MS\t${_noop.toString().replace('\n', '')}\tISNOOP? ${_noop() === undefined}`);
    return elapsed;
}

const iterations = 10000000
console.info(`noop time for ${iterations.toLocaleString()} iterations`)
const timings = {
    noop: test(noop, iterations),
    noopProto: test(noopProto, iterations)
}

const percentFaster = ((timings.noopProto - timings.noop)/timings.noopProto).toLocaleString("en-us", { style: "percent" });
console.info(`()=>{} is ${percentFaster} faster than Function.prototype in the current browser!`)
Run Code Online (Sandbox Code Playgroud)

  • 我创建了一个 jsPerf 测试来比较一些选项:[noop-function](https://jsperf.com/noop-function)。似乎在 Firefox 54 中,所有替代方案似乎都差不多;在 Chromium 58 中,`Function.prototype` 的速度要慢得多,但其他选项都没有明显的优势。 (2认同)

zmo*_*zmo 15

你在这里所取得的成就是错误的.三元表达式不得仅用于表达式的完整陈述,因此您的问题的答案是:

没有你的建议,而是:

var a = 2;
if (a === 1)
    alert(1)
// else do nothing!
Run Code Online (Sandbox Code Playgroud)

然后代码很容易理解,可读并且尽可能高效.

为什么它变得更加困难,什么时候可以简单?

编辑:

那么,"无操作"命令基本上是否表示较差的代码结构?

你错过了我的观点.以上都是关于三元表达的x ? y : z.

但是,在诸如Javascript之类的更高级语言中,没有操作命令是没有意义的.

它通常在较低级语言(如汇编语言或C语言)中使用,作为使处理器不为一条指令执行任何操作以进行计时的方法.

在JS,无论你做0;,null;,function () {};或空语句,有很大的机会,它会被解释器时,它读取它忽略,但之前它被解释,所以到最后,你只会让你的程序是在很短的时间内加载得更慢.Nota Bene:我假设这一点,因为我没有参与任何广泛使用的JS解释器,并且每个解释器都有自己的策略.

如果您使用的东西有点复杂,比如$.noop()或者var foo = function () {}; foo(),那么解释器可能会执行一个无用的函数调用,最终会破坏函数堆栈的几个字节,并且会有几个周期.

我看到一个函数$.noop()存在的唯一原因就是能够仍然给某个事件函数提供一个回调函数,如果它不能调用该回调就会引发异常.但是,它必然是你需要给予的一个功能,并给它起noop一个好主意,所以你告诉你的读者(可能是你在6个月内),你故意给出一个空功能.

最后,没有"劣等"或"优越"的代码结构.你使用工具的方式要么是对的.使用三元作为你的例子就像在你想要拧螺丝时使用锤子.它会工作,但你不确定你可以挂在那个螺丝上.

可以被认为是"劣等"或"高级"的是您在代码中添加的算法和想法.但那是另一回事.

  • @kmiklas:我不能说我曾经在汇编程序之外找到了合法的NOOP需求. (3认同)
  • 当然,有理由想要/需要无操作功能。不要根据你对某事的 12 秒深入思考做出广泛的概括。JavaScript 是一种使函数作为变量完全可控的语言。假设您需要在没有显式测试的情况下禁用某个功能?这将是完美的。如果您有一个经常出现的函数,例如调试语句,那么能够通过将函数重新分配给 no-op 来关闭它会很好,而不必在每次函数出现时添加额外的代码来测试某个变量. (2认同)
  • @bearvarine谢谢您对我的高度评价:-D。您的评论绝对正确,但这并不是真正的代码设计,只是使用hack的模型设计。您所描述的也称为猴子修补,这是有原因的;-) (2认同)

Saw*_*oes 9

使用Function.prototypeover绝对不会有任何问题或性能损失() => {}

\n\n

其主要好处Function.prototype是拥有单例函数,而不是每次都重新定义新的匿名函数。Function.prototype在定义默认值和记忆时使用无操作尤其重要,因为它为您提供了一个永远不会改变的一致的对象指针。

\n\n

我推荐Function.prototype而不是Function因为它们不一样:

\n\n
Function() === Function()\n// false\n\nFunction.prototype() === Function.prototype()\n// true\n
Run Code Online (Sandbox Code Playgroud)\n\n

此外,其他答案的基准具有误导性。事实上,Function.prototype执行速度比() => {}取决于您如何编写和运行基准测试要快:

\n\n

你可以\xe2\x80\x99t信任JS基准<<专门针对这个问题提出基准。

\n\n

不要根据基准来设计代码;做任何可维护的事情,并让解释器弄清楚如何从长远来看进行优化。

\n


lea*_*eaf 6

我认为jQuery noop()主要是为了防止代码在请求的函数不可用时提供默认函数而崩溃.例如,考虑以下代码示例,$.noop如果fakeFunction未定义则选择,以防止下一次调用fn崩溃:

var fn = fakeFunction || $.noop;
fn() // no crash
Run Code Online (Sandbox Code Playgroud)

然后,noop()允许通过避免在代码中的任何地方多次写入相同的空函数来节省内存.顺便说一句,$.noop有点短function(){}(每个令牌节省6个字节).因此,您的代码与空函数模式之间没有关系.使用null,false或者0如果您愿意,在您的情况下,将没有副作用.此外,值得注意的是这段代码......

true/false ? alert('boo') : function(){};
Run Code Online (Sandbox Code Playgroud)

...完全没用,因为你永远不会打电话给这个功能,而这一个......

true/false ? alert('boo') : $.noop();
Run Code Online (Sandbox Code Playgroud)

...因为你调用一个空函数更加无用,这与...完全相同

true/false ? alert('boo') : undefined;
Run Code Online (Sandbox Code Playgroud)

让我们用一个if语句替换三元表达式,看看它有多大用处:

if (true/false) {
    alert('boo');
} else {
    $.noop(); // returns undefined which goes nowhere
}
Run Code Online (Sandbox Code Playgroud)

你可以简单地写:

if (true/false) alert('boo');
Run Code Online (Sandbox Code Playgroud)

甚至更短:

true/false && alert('boo');
Run Code Online (Sandbox Code Playgroud)

为了最终回答你的问题,我认为"传统的无操作"是从未写过的.

  • 但是有时您必须提供一个函数。例如,使用 promise then(fn, fn) 有时您想提供第二个函数而不是第一个函数。因此你需要一些东西作为占位符...... `mypromise.then($.noop, myErrorhandler);` (2认同)