对于无操作的 JavaScript 约定是什么?

什么是 JavaScript 约定不用操作? 类似于 Pythonpass命令。

  • 一个选项是一个简单的空函数: function() {}
  • JQuery 提供了 $.noop(),它只调用上面的空函数。
  • 只输入 false0的值是否可以接受?

在上下文中... ... 所有这些工作都不会在 Chrome 中出现错误:

var a = 2;
(a === 1) ? alert(1) : function() {};
(a === 1) ? alert(1) : $.noop();
(a === 1) ? alert(1) : false;
(a === 1) ? alert(1) : 0;

编辑: 很多人回应说: “不要这样做!改变代码结构!”这让我想起了一个帖子,有人问我如何闻浏览器。他收到了一连串的帖子,上面写着: “不要那样做!但是 没人告诉他怎么闻浏览器。这不是代码审查。假设您正在处理无法更改的遗留代码,如果没有传入某个函数,它将抛出一个错误。或者,简单地说,这就是客户想要的方式,以及 他们付我钱。那么,请问 回答问题: 在 JavaScript 中指定“ no operation”函数的最佳方法是什么?

编辑2: 这个怎么样?

true;
false;
0;
1;
null;
110741 次浏览

不管你想在这里达到什么目的都是错误的。三元表达式 不会用作完整的陈述,只用于表达,因此对你的问题的答案是:

不是你的建议,而是:

var a = 2;
if (a === 1)
alert(1)
// else do nothing!

那么代码就很容易理解、可读并且尽可能地高效。

既然可以很简单,为什么还要让它变得更难呢?

编辑:

那么,“ no-operation”命令是否基本上意味着低级的代码结构?

你没明白我的意思。以上所有内容都是关于三元表达式 x ? y : z的。

但是,no operation 命令在诸如 Javascript 这样的高级语言中没有意义。

在汇编语言或 C 等低级语言中,它通常被用作一种方法,使处理器不对一条指令执行任何操作,以达到计时的目的。

在 JS 中,无论是执行 0;null;function () {};还是执行空语句,解释器在读取时很有可能会忽略它,但是 之前会被解释,所以最终,你只会让程序加载的速度变得更慢,只有很短的一段时间。不好: 我是这样假设的,因为我没有参与任何广泛使用的 JS 解释器,而且每个解释器都有自己的策略。

如果您使用的是比较复杂的函数,比如 $.noop()var foo = function () {}; foo(),那么解释器可能会执行一个无用的函数调用,最终会损坏函数堆栈的几个字节和几个周期。

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

最后,没有所谓的“低级”或“高级”代码结构。你使用工具的方式不是对就是错。.在你的例子中使用三元组就像当你想要拧螺丝的时候使用锤子一样。会有用的,但你不确定能不能把什么东西挂在螺丝上。

什么可以被认为是“劣等”或“优越”是算法和思想,您放在您的代码。但那是另一回事。

我认为 jQuerynoop()主要是为了防止代码崩溃,在请求的函数不可用时提供一个默认函数。例如,考虑到下面的代码示例,如果没有定义 fakeFunction,则选择 $.noop,防止下一个对 fn的调用崩溃:

var fn = fakeFunction || $.noop;
fn() // no crash

然后,noop()允许通过避免在代码中的任何地方多次编写相同的空函数来节省内存。顺便说一下,$.noopfunction(){}短一点(每个令牌节省6个字节)。因此,代码和空函数模式之间没有关系。使用 nullfalse0,如果你喜欢,在你的情况下将没有副作用。此外,值得注意的是,这个代码..。

true/false ? alert('boo') : function(){};

... 完全没用,因为你永远不会调用函数,而这个..。

true/false ? alert('boo') : $.noop();

... 更没用,因为你调用了一个空函数,这和..。

true/false ? alert('boo') : undefined;

让我们用 if语句替换这个三元表达式,看看它有多么无用:

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

你可以简单地写:

if (true/false) alert('boo');

或者更短:

true/false && alert('boo');

最后回答你的问题,我想“传统的无操作”是一个从来没有写。

为了回答最初的问题,纯 Javascript 中 noop 函数(也讨论了 给你)的最优雅和最简洁的实现是 功能,原型。这是因为:

  1. 原型是一个函数:

typeof Function.prototype === "function" // returns true

  1. 它可以作为一个函数调用,基本上什么也不做,如下所示:
setTimeout(function() {
console.log('Start: ', Date.now());
Function.prototype();
console.log('End  : ', Date.now());
}, 1000);

虽然这是一个“真正的 noop”,因为大多数浏览器似乎没有做任何事情来执行这种方式定义的 noop (因此节省 CPU 周期) ,可能会有一些与此相关的性能问题(正如其他人在评论或其他答案中提到的)。

但是,也就是说,您可以很容易地定义自己的 noop 函数,事实上,许多库和框架也提供 noop 函数。下面是一些例子:

var noop = function () {};           // Define your own noop in ES3 or ES5
const noop = () => {};               // Define in ES6 as Lambda (arrow function)
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 AngularJS 1.x
setTimeout(jQuery.noop, 10000);      // Using with jQuery

下面按字母顺序列出了 noop 函数的各种实现(或相关讨论或谷歌搜索) :

AngularJS 1.x 翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳(似乎没有本地的 余烬< strong > jQuery < strong > Lodash < strong > NodeJS 拉姆达返回文章页面反应译者:(似乎没有本地实现-使用你自己的,如上所示) ,< strong > RxJS , 下划线

底线 : 尽管 Function.model 是在 Javascript 中表达 noop 的一种优雅的方式,但是,可能会有一些与其使用相关的性能问题。因此,您可以定义并使用您自己的(如上所示)或使用您可能在代码中使用的库/框架定义的。

最简洁和性能的 noop 是 空箭头函数空箭头函数: ()=>{}

箭头函数 在除 IE 之外的所有浏览器中都可以本机工作(如果必须的话,还有一个 巴别变形术) : MDN


()=>{}Function.Prototype

  • 在 Chrome67中,()=>{}快了87% 而不是 Function.prototype
  • 在 Firefox 60中,()=>{}快了25% 而不是 Function.prototype
  • 在边缘 (6/15/2018)中,()=>{}快了85% 而不是 Function.prototype
  • ()=>{}代码减少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!`)

我用:

 (0); // nop

以下方式测试此运行的执行时间:

console.time("mark");
(0); // nop
console.timeEnd("mark");

结果: 标记: 0.000毫秒

使用 Boolean( 10 > 9)可以简化为返回 true的简单 ( 10 > 9)。提出使用单个操作数的想法时,我完全预料到 (0);会返回 false,但它只是返回参数,因为可以通过在控制台上执行这个测试来查看这个参数。

> var a = (0);
< undefined
> a
< 0

() => {}上使用 Function.prototype绝对没有问题或性能损失。

Function.prototype的主要好处是有一个单例函数,而不是每次都重新定义一个新的匿名函数。在定义默认值和制表时,使用类似 Function.prototype的 no-op 非常重要,因为它为您提供了一致的对象指针,而且永远不会改变。

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

Function() === Function()
// false


Function.prototype() === Function.prototype()
// true

事实上,Function.prototype的执行速度比 () => {}快,这取决于你如何编写和运行基准测试:

你不能信任 JS 基准 < < 特别是在这个问题上调用基准。

不要根据基准测试来设计代码的样式; 做任何可维护的事情,让解释器找出如何从长远来看进行优化的方法。