4

With ES6, I can create a new object with functions like the following:

var obj = {
    something() {}
};

That makes sense. But I can also do this:

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

Or I can do this:

var obj = {
    ['something']() {}
};

Is there a difference between these three syntaxes? Why are all of these syntactically valid?

apscience
  • 7,033
  • 11
  • 55
  • 89

2 Answers2

6

Is there a difference between these three syntaxes?

Not wrt to the results in your example.

However, the different syntaxes do have different characteristics. The way the property name is defined is not specific to method definitions btw, the rules apply to all property names:

  • 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)]: ...,
    }
    

Why are all of these syntactically valid?

Because the grammar allows it:

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

PropertyName :
    LiteralPropertyName
    ComputedPropertyName

LiteralPropertyName :
    IdentifierName
    StringLiteral
    NumericLiteral

ComputedPropertyName :
    [ AssignmentExpression ]

(not sure what kind of answer you expect here)

If you consider methods to be equivalent to assigning a function to the property, it seems to make sense to apply the same rules for property names to function/method names.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • As it turns out, you can do `['foo' + someFunction()]` with brackets and have dynamic (on-creation) property names. Neat trick. – apscience Mar 03 '16 at 23:53
  • "*except for the function names*" - shouldn't even these be the same? – Bergi Mar 04 '16 at 00:12
  • @Bergi: I meant what georg was pointing out in his answer. The last one doesn't set the name of the function. I should clarify that. – Felix Kling Mar 04 '16 at 00:13
  • 1
    @FelixKling: Actually it does? [Pretty useful](http://stackoverflow.com/a/9479081/1048572) even – Bergi Mar 04 '16 at 00:20
  • @Bergi: I see now. (the demo doesn't seem to work in latest Chrome though :-/) – Felix Kling Mar 04 '16 at 00:23
2

First and second are the same, and do the same as

obj.something = function something() {}

the third one creates an anonymous function and stores it in obj.something. It's an equivalent to this:

obj['something'] = function() {}

Quotes allow to create keys (and hence function names) that are not valid identifiers in JS, for example:

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

creates a function with the name 123, believe it or not.

The square brackets syntax allows arbitrary expressions, so you can do

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

and similar cool things.

georg
  • 211,518
  • 52
  • 313
  • 390
  • *"...and do the same as..."* Except that `something` isn't bound inside the function. – Felix Kling Mar 03 '16 at 23:54
  • 3
    @zerkms: Yes: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-method-definitions-runtime-semantics-propertydefinitionevaluation (step 3) – Felix Kling Mar 03 '16 at 23:57
  • FWIW, `var obj = { 123() {} };` is valid too. – Felix Kling Mar 04 '16 at 00:07
  • @FelixKling: thanks for the link, what I don't understand it why `[...]()` doesn't do SetFunctionName. The standard doesn't seem to care if a PropertyName is Literal or Computed. – georg Mar 04 '16 at 00:10
  • For a computed property name, the [`PropName` procedure](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object-initializer-static-semantics-propname) returns "emtpy", i.e. the name cannot be set to anything. – Felix Kling Mar 04 '16 at 00:11
  • 1
    @FelixKling: ah, makes sense (well, it doesn't actually, but that's ECMA for you...) – georg Mar 04 '16 at 00:15
  • 1
    @FelixKling: `PropName` doesn't matter for `SetFunctionName`. It's only used statically to prevent duplicate `constructor`s, static `prototype` properties and similar in classes. – Bergi Mar 04 '16 at 00:22