如果对象存在,JavaScript中调用方法的简写形式

9

我有一个变量,如果这个变量是一个对象,我想调用该对象的一个方法,如果不是,我就不想做任何事情。

我想知道是否有任何理由不这样做。

var foo = null;

  ////////////////////////////////////////////////
  // some code that could change foo to a object
  ////////////////////////////////////////////////

 foo && foo.bar();

@Rayon 如果我们都知道自己在做什么,那我们就不会来到 StackOverFlow 上了。 - cmac
1
我的观点是,如果它按预期工作,请忙于了解它的工作原理。如果你能理解,就去做吧,因为你可以解决未来可能出现的问题。如果你无法理解,就选择更简单易读的版本。 - Rayon
@Rayon 没错,谢谢!我只是问一下,因为我经常看到其他方式,比如 ((typeof foo === 'object') && foo.bar()),而不是像这样的写法:foo && foo.bar(); ... 这种写法更短、更干净,更容易理解。所以,我只是想知道是否有什么我不知道的东西。 - cmac
1
@cmac 这个模式并没有什么新意。更多的是对 falsey 和运算符的理解... - Rayon
2
不确定为什么OP在这里遇到了困难。这是一个合理的问题(可能是重复的,我猜)。 我理解这个问题是“如果foo为null,则表达式会抛出异常吗?(含蓄地)表达式的值是什么?” 我的答案是:“当foo为null时,该表达式正常工作(其值为null),并且当foo为实现bar()的对象时,它也正常工作(其值为bar()的返回值)。 - danh
显示剩余5条评论
4个回答

19

使用ES6,您可以将可选链运算符call结合使用:

foo?.bar?.call()
如果想要传递参数,请记住调用中的第一个参数会将this指向函数调用。
var foo = {
  bar: function(x) { return x; }
};

first.value  = foo?.bar?.call(0,42); // 42
second.value = foo?.baz?.call(0,42); // undefined, no error
<input id="first">
<input id="second">


5
不必使用 call,你可以直接使用可选链来调用函数:foo?.bar?.()。这不仅更短,而且在 TypeScript 中也更好用,因为它会提供智能感知,而不是使用 call - Jonathan
似乎即使在Typescript中也不再需要这样做了。你只需使用foo?.bar(),它将按预期工作。 - undefined

4
简单回答是,如果foonull,那么foo && foo.bar()不会抛出异常;如果foo有值,则会评估bar()并将其值作为表达式的值。
更长的回答是,任何值都可以被解释为布尔值,因为每个值都是真值或假值,并且布尔运算符采用短路计算--从左到右,如果我们看到一个false &&true ||,就没有理由继续评估。
最后一个事实是,布尔表达式的值是发生短路时表达式的值。

1
你需要将一个对象分配给foo,并且该对象应该有一个函数属性。

var foo;

foo = {};
foo.bar = function () {
    console.log('inside bar');
};

foo && foo.bar && foo.bar();


0
((typeof foo === 'object') && foo.bar())

或者

(!(typeof foo == 'object') || foo.bar())

如果foo是对象类型,则执行。
请参见我的答案{{link1:javascript使用或运算符迭代字符串列表}}。
这是一个“常见”的问题,如果某些人在这样的序列中使用赋值并忘记评估在 || 序列中在第一个true后停止,或在&&中在第一个false后停止。

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