ES6对象方法赋值的区别:a,'a'和['a']之间有什么不同?

4

使用ES6,我可以通过以下函数创建一个新对象:

var obj = {
    something() {}
};

这很有道理。但我也可以这样做:
var obj = {
    'something'() {}
};

我可以这样做:
var obj = {
    ['something']() {}
};

这三种语法有什么不同?为什么所有这些语法都是语法上有效的?

哇,我不知道你可以在字面值中使用 ['x'] - Onur Yıldırım
真的很好奇是否有使用最后一个的任何好处。 - Chris
@Chris:是的,你可以使用[Math.random()] - apscience
@Chris:好处在于你可以编写一个名为['1.2e+35'] = 7的属性。 - Tal Avissar
1
@TalAvissar,你可以不用方括号来实现这个。 - zerkms
2个回答

6

这三种语法有区别吗?

就你的例子而言,结果没有区别。

但是,不同的语法确实具有不同的特点。属性名称的定义方式并不特定于方法定义,规则适用于所有属性名称:

  • Property names that are valid identifier names or number literals don't need to be quoted:

    {
      foo: ...,
      10e4: ...,
      if: ...,
    }
    
  • Anything else needs to be quoted:

    {
      'foo+bar': ...,
      'abc def': ...,
      '123,45': ...,
    }
    
  • The square bracket syntax is new in ES6 and allows you do dynamically compute property names:

    {
       [getPropertyName()]: ...,
       ['item' + (i * 3)]: ...,
    }
    

为什么这些语法都是有效的?

因为语法允许它:

MethodDefinition :
    PropertyName ( StrictFormalParameters ) { FunctionBody }
    GeneratorMethod
    get PropertyName ( ) { FunctionBody }
    set PropertyName( PropertySetParameterList ) { FunctionBody }

PropertyName :
    LiteralPropertyName
    ComputedPropertyName

LiteralPropertyName :
    IdentifierName
    StringLiteral
    NumericLiteral

ComputedPropertyName :
    [ AssignmentExpression ]

如果您将方法视为将函数分配给属性,则对于函数/方法名称应适用与属性名称相同的规则似乎是有意义的。


结果证明,您可以使用括号进行 ['foo' + someFunction()] 并具有动态(创建时)属性名称。很巧妙的技巧。 - apscience
except for the function names” - 这些函数名字也不应该相同吗? - Bergi
@Bergi:我的意思是乔治在他的回答中指出的问题。最后一个没有设置函数的名称。我应该澄清一下。 - Felix Kling
1
@FelixKling:事实上它确实可以。非常有用,甚至。 - Bergi
@Bergi:我现在明白了。(然而演示似乎不能在最新版本的Chrome中工作 :-/) - Felix Kling

2

第一和第二个是相同的,并且执行的操作也是相同的

obj.something = function something() {}

第三个函数创建一个匿名函数并将其存储在obj.something中。它相当于这个:
obj['something'] = function() {}

引号允许创建在JS中不是有效标识符(函数名称)的键,例如:

 var obj = {
    '123'() {}
};

创建一个名为123的函数,信不信由你。

方括号语法允许使用任意表达式,因此您可以执行以下操作:

 var obj = {
   ['myfunc_' + getFuncName()] () {}
 }

以及类似的酷东西。


3
@zerkms:是的:http://www.ecma-international.org/ecma-262/6.0/index.html#sec-method-definitions-runtime-semantics-propertydefinitionevaluation(第3步) - Felix Kling
顺便说一句,var obj = { 123() {} }; 也是有效的。 - Felix Kling
@FelixKling:感谢提供链接,但我不明白为什么[...]()不能执行SetFunctionName。标准似乎并不关心PropertyName是Literal还是Computed。 - georg
1
@FelixKling:啊,有道理(其实并没有,但这就是 ECMA 的风格……) - georg
1
@FelixKling:对于SetFunctionName来说,PropName并不重要。它只在静态上下文中使用,以防止类中出现重复的constructors、静态prototype属性等。 - Bergi
显示剩余2条评论

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