【问题标题】:Execute function in command pattern JavaScript在命令模式 JavaScript 中执行函数
【发布时间】:2013-07-19 02:32:08
【问题描述】:

我目前正在阅读 Addy Osmani 的 JavaScript 设计模式,可以在这里找到:http://addyosmani.com/resources/essentialjsdesignpatterns/book/

我觉得这很有趣,也很有帮助。我确实对书中的一种模式有疑问,即命令模式。

在书中,Addy 解释了命令模式有助于更好地解耦对象和方法调用。

这是我的例子:

var person = {
    sayName: function (name) {
        return "My name is " + name;
    },
    sayAge: function (age) {
        return "My age is " + age;
    },
    sayGender: function (gender) {
        return "My gender is " + gender;
    }
}
person.execute = function (name) {
    return person[name] && person[name].apply(person, [].slice.call(arguments, 1));
}
console.log(person.execute("sayName", "Sethen"));

魔术是在执行方法中完成的。如您所见,您传递方法名称和参数,然后由方法处理其余部分。

我的困惑源于 execute 方法实际返回的内容。当您查看它时,它看起来像是与 && 的短路,我一直认为由于 JavaScript 转换而返回了布尔值。

但是,如果您尝试代码,它会完全按照应有的方式运行,记录 My name is Sethen

此外,我发现简单地使用 return person[name].apply(person, [].slice.call(arguments, 1); 会产生相同的结果,并且在我看来更容易阅读。

所以,我的问题是 return 在原始 execute 方法中的工作原理:

return person[name] && person[name].apply(person, [].slice.call(arguments, 1));

以及&& 运算符在此实例中如何工作以使其正常工作??

【问题讨论】:

  • 抱歉,您能否尝试使问题更简洁,这是您写的最后一行中唯一重要的部分
  • 见:*.com/questions/5049006/…。这甚至可能是重复的。
  • 有趣的是,当您尝试执行不存在的方法而不是引发异常时,此模式将返回 undefined
  • 这不是命令模式。查看jsfiddle.net/eAyCF/1 的示例——以及为什么 JS 不需要它的解释。
  • @SethenMaleno:是的。封装稍后可能执行的操作基本上是命令模式的重点。一旦函数可以是值,模式就不再有用了——你只需使用一个闭包,而不是一个命令对象。

标签: javascript


【解决方案1】:

&& 运算符并不总是返回 boolean。它返回它计算的最后一个子表达式的值。如果请求的方法名称存在,则该表达式将返回 .apply() 调用的结果。

所以:

return person[name] && person[name].apply(person, [].slice.call(arguments, 1));

意思是:

if (!person[name])
  return person[name];

return person[name].apply(person, [].slice.call(arguments, 1));

【讨论】:

  • 那么,基本上第一部分只是检查以确保方法名称确实存在??
  • @SethenMaleno 是的,完全正确。 (好吧,严格来说,方法名称可以作为“person”对象的属性存在,但如果它的值看起来不“真实”,则测试失败。出于示例的目的,当然,它正在检查确保该方法存在。)
  • @aaronman &&|| 的行为是该语言中最聪明的设计决策之一,在我看来 :) 它们比(例如)Java 有用得多版本。
  • 是的,如果不是因为分配泄漏,您将不得不使用三元组进行默认设置,就像在其他语言中一样。 && 允许单表达式查询,这非常快:return a && a.prop=='ok' && a;
【解决方案2】:

在这种情况下,&& 的行为有点像 if 语句。

如果您要传入不是该对象上的方法的东西,那将是错误的,并且不会继续执行该语句的其余部分。

【讨论】: