我们从声明中扔掉了单词 function
,这使所有的 JS 开发者欢呼!
你可能已经注意到,而且为此感到沮丧:上面推荐的 OLOO 语法出现了许多 function
,这看起来像是对 OLOO 简化目标的诋毁。但它不必是!
在 ES6 中,我们可以在任何字面对象中使用 简约方法声明,所以一个 OLOO 风格的对象可以用这种方式声明(与 class
语法中相同的语法糖):
var LoginController = {
errors: [],
getUser() { // 看,没有 `function`!
// ...
},
getPassword() {
// ...
}
// ...
唯一的区别是字面对象的元素间依然需要 ,
逗号分隔符,而 class
语法不必如此。这是在整件事情上很小的让步。
ES6 中的 OLOO 风格,与简明方法一起,变得比它以前 友好得多(即使在以前,它也比经典的原型风格代码简单好看的多)。 你不必非得选用类(复杂性)来得到干净漂亮的对象语法!
简约方法确实有一个缺点,一个重要的细节。考虑这段代码:
var Foo = {
bar() { /*..*/ },
baz: function baz() { /*..*/ }
};
这是去掉语法糖后,这段代码将如何工作:
看到区别了?bar()
的速记法变成了一个附着在 bar
属性上的 匿名函数表达式(function()..
),因为函数对象本身没有名称标识符。和拥有词法名称标识符 baz
,附着在 .baz
属性上的手动指定的 命名函数表达式(function baz()..
)做个比较。
一个匿名函数缺少 name
标识符:
- 使调试时的栈追踪变得困难
- 使自引用(递归,事件绑定等)变得困难
- 使代码(稍稍)变得难于理解
第一和第三条不适用于简明方法。
虽然去掉语法糖使用 匿名函数表达式 一般会使栈追踪中没有 name
。简明方法在语言规范中被要求去设置相应的函数对象内部的 name
属性,所以栈追踪应当可以使用它(这是依赖于具体实现的,所以不能保证)。
不幸的是,第二条 仍然是简明方法的一个缺陷。 它们不会有词法标识符用来自引用。考虑:
bar: function(x) {
if (x < 10) {
}
return x;
},
baz: function baz(x) {
if (x < 10) {
return baz( x * 2 );
}
return x;
}
};
只要小心简明方法的这个注意点,而且如果当你陷入缺少自引用的问题时,仅仅为这个声明 放弃简明方法语法,取代以手动的 命名函数表达式 声明形式:baz: function baz(){..}
。