"if (fn) fn()" or "fn && fn()"

7
我曾多次看到fn && fn()if(fn) fn()的一种优化方式。我的问题是:为什么这样做?这两种方法所生成的代码分别是什么?

2
“生成的代码”是什么意思? - Kobi
@Kobi 我猜他的意思是指JavaScript编译成的低级代码。 - kba
@kobi,kba是对的,我指的是低级代码,汇编语言。 - Gabriel Llamas
JavaScript是一种解释性语言,因此它不一定会编译成任何东西。请参见https://dev59.com/ZFrUa4cB1Zd3GeqPnc0u。 - JJJ
1
@juhana JavaScript是一种解释型语言,这是其设计之一。 - Gabriel Llamas
3个回答

14
在JavaScript中,&&运算符是有短路效应的,这意味着如果左侧为false,则右侧不会被评估。因此,即使fn为falsey(null, undefined等),fn && fn()是安全的。
生成的代码完全取决于JavaScript引擎,但我希望这两种情况下(&&if)的代码非常相似。
它并不是指跑得更快的“优化”,而是指书写更简短(特别是如果像我一样从不在if语句中省略{})。它的缺点是对于新手来说稍微不够清晰,但它是一个很快就能学会的习惯用法。

typeof fn === "function" 不是更安全吗? - Antony
@Antony:是的,它会。你会在代码期望函数或无值(例如,可选函数参数)的地方看到这个习惯用语,如果你给它一个不是函数的东西,它失败了,人们倾向于认为这是可以接受的,因为函数(例如)的文档说你可以提供一个函数或无值,但不能提供一个函数或(比如)字符串。 :-) 此外,一些引擎上的主机提供的函数具有typeof“object”(可悲的是),但仍然可调用。 - T.J. Crowder

2
因此,通过 if (fn) fn(),你想确保在执行之前 fn 存在。在 JavaScript 中,if 条件检查一个布尔值或表达式,任何 falsy 值都可以在 if 布尔检查条件中变成一个 false 值。Falsy 值包括:
  • false
  • null
  • undefined
  • 空字符串 ''
  • 数字 0
  • 数字 NaN(是的,“不是数字”是一个数字,它是一个特殊的数字)

任何其他值都是 truthy 值。

因此,如果 fn 是一个 nullundefined 值,则 if 检查将保护您免于执行非函数对象。

通过 fn && fn(),您正在执行相同的操作:在 JavaScript 中,布尔表达式是懒惰检查的,这意味着如果第一部分在 && 操作中是 falsy 的,则第二部分将不会被执行。因此,使用此功能,您可以保护代码免于执行非函数对象。

fn && fn() 在性能方面并不是另一个版本的优化版本,但在书写方面是一个简短的版本。

这两个代码片段都需要一个前提条件:函数 fn 可能未定义或为实际函数对象。如果在您的代码中,fn 有可能是其他类型的对象,例如字符串,则需要在执行之前添加类型检查,例如:

if (fn instanceof Function) fn()


0
就优化而言,我个人认为这是一种更好的方法,可以将其变成一行if then,而无需牺牲大括号和可读性,但这并不会使代码执行更快。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接