Skip to main content
Stack Overflow
  1. About
  2. For Teams

Return to Answer

clarify method syntax
Source Link
T.J. Crowder
  • 1.1m
  • 201
  • 2k
  • 2k

ES2015 allows a shorter form of declaring a property that references a function;function called a method definition; it looks like this:

the equivalentalmost-equivalent in ES5 and earlier would be:

the difference (other than verbosity) is that a method can use super, but a function cannot. So for instance, if you had an object that defined (say) valueOf using method syntax, it could use super.valueOf() to get the value Object.prototype.valueOf would have returned (before presumably doing something else with it), whereas the ES5 version would have to do Object.prototype.valueOf.call(this) instead.

That also means that the method has a reference to the object it was defined on, so if that object is temporary (for instance, you're passing it into Object.assign as one of the source objects), method syntax could mean that the object is retained in memory when otherwise it could have been garbage collected (if the JavaScript engine doesn't detect that situation and handle it if none of the methods uses super).

ES2015 allows a shorter form of declaring a property that references a function; it looks like this:

the equivalent in ES5 and earlier would be:

ES2015 allows a shorter form of declaring a property that references a function called a method definition; it looks like this:

the almost-equivalent in ES5 and earlier would be:

the difference (other than verbosity) is that a method can use super, but a function cannot. So for instance, if you had an object that defined (say) valueOf using method syntax, it could use super.valueOf() to get the value Object.prototype.valueOf would have returned (before presumably doing something else with it), whereas the ES5 version would have to do Object.prototype.valueOf.call(this) instead.

That also means that the method has a reference to the object it was defined on, so if that object is temporary (for instance, you're passing it into Object.assign as one of the source objects), method syntax could mean that the object is retained in memory when otherwise it could have been garbage collected (if the JavaScript engine doesn't detect that situation and handle it if none of the methods uses super).

added 730 characters in body
Source Link
T.J. Crowder
  • 1.1m
  • 201
  • 2k
  • 2k
  • Function Declaration

  • "Anonymous" function Expression (which despite the term, sometimes getcreate functions with names)

  • Named function Expression

  • Accessor Function Initializer (ES5+)

  • Arrow Function Expression (ES2015+) (these are alsowhich, like anonymous in naturefunction expressions, don't involve an explicit name, and yet sometimes getcan create functions with names)

  • Method Declaration in Object Initializer (ES2015+)

  • Constructor and Method Declarations in class (ES2015+)

In ES5, the function this creates has no name (it's anonymous). In ES2015, the function is assigned a name if possible by inferring it from context. In the example above, the name would be y. Something similar is done when the function is the value of a property initializer. (For details on when this happens and the rules, search for SetFunctionName in the ES2015 specification the specification — it appears all over the place.)

  1. TheirThey don't have their own this is. Instead, they lexically boundclose over, not determined when they're called. This means that the this of the context where they're defined. (They also close over arguments and, where relevant, super.) This means that the this within them is the same as the this where they're created, and cannot be changed.

  2. As you'll have noticed with the above, you don't use the keyword function; instead, you use =>.

In both cases, the body of the function is just an expression; the function's return value will automatically be the result of that expression (you don't use an explicit return).

If you're doing more than just a single expression, use {} and an explicit return (if you need to return a value), as normal:

The version without { ... } is called an arrow function with an expression body or concise body. (Also: A concise arrow function.) The one with { ... } defining the body is an arrow function with a function body. (Also: A verbose arrow function.)

  • Function Declaration

  • "Anonymous" function Expression (which despite the term, sometimes get names)

  • Named function Expression

  • Accessor Function Initializer (ES5+)

  • Arrow Function Expression (ES2015+) (these are also anonymous in nature, and yet sometimes get names)

  • Method Declaration in Object Initializer (ES2015+)

  • Constructor and Method Declarations in class (ES2015+)

In ES5, the function this creates has no name (it's anonymous). In ES2015, the function is assigned a name if possible by inferring it from context. In the example above, the name would be y. Something similar is done when the function is the value of a property initializer. (For details on when this happens and the rules, search for SetFunctionName in the ES2015 specification — it appears all over the place.)

  1. Their this is lexically bound, not determined when they're called. This means that the this within them is the same as the this where they're created.

  2. As you'll have noticed with the above, you don't use the keyword function; instead, you use =>.

If you're doing more than just a single expression, use {} as normal:

  • Function Declaration

  • "Anonymous" function Expression (which despite the term, sometimes create functions with names)

  • Named function Expression

  • Accessor Function Initializer (ES5+)

  • Arrow Function Expression (ES2015+) (which, like anonymous function expressions, don't involve an explicit name, and yet can create functions with names)

  • Method Declaration in Object Initializer (ES2015+)

  • Constructor and Method Declarations in class (ES2015+)

In ES5, the function this creates has no name (it's anonymous). In ES2015, the function is assigned a name if possible by inferring it from context. In the example above, the name would be y. Something similar is done when the function is the value of a property initializer. (For details on when this happens and the rules, search for SetFunctionName in the the specification — it appears all over the place.)

  1. They don't have their own this. Instead, they close over the this of the context where they're defined. (They also close over arguments and, where relevant, super.) This means that the this within them is the same as the this where they're created, and cannot be changed.

  2. As you'll have noticed with the above, you don't use the keyword function; instead, you use =>.

In both cases, the body of the function is just an expression; the function's return value will automatically be the result of that expression (you don't use an explicit return).

If you're doing more than just a single expression, use {} and an explicit return (if you need to return a value), as normal:

The version without { ... } is called an arrow function with an expression body or concise body. (Also: A concise arrow function.) The one with { ... } defining the body is an arrow function with a function body. (Also: A verbose arrow function.)

clarify function declarations in blocks
Source Link
T.J. Crowder
  • 1.1m
  • 201
  • 2k
  • 2k
  • Function Declaration

  • "Anonymous" function Expression (which despite the term, sometimes get names)

  • Named function Expression

  • Accessor Function Initializer (ES5+)

  • Arrow Function Expression (ES2015+)(these are also anonymous in nature, and yet sometimes get names)

  • Method Declaration in Object Initializer (ES2015+)

  • Constructor and Method Declarations in class (ES2015+)

Also because it's not part of the step-by-step execution of the codeUntil ES2015, the spec didn't cover what a JavaScript engine should do if you can't put ita function declaration inside a control structure like try, if, switch, while, etc., like this:

if (someCondition) {
 function foo() { // <===== INVALID AND WILL FAILHERE ONTHERE
 } // <===== MANYBE ENGINESDRAGONS
}

Some engines will handle the above even though it's invalid, by rewriting it as a function expression onAnd since they're processed before step-theby-fly. There's talk of addingstep code is run, it's tricky to know what to do when they're in a control structure.

Although doing this wasn't function statementspecified until ES2015, it was an allowable extension to the next specsupport function declarations in blocks. Unfortunately (ECMAScript6and inevitably), different engines did different things.

As of ES2015, the specification says what to codify thatdo. But with current enginesIn fact, it will not work reliably; don'tgives three separate things to do it:

  1. If in loose mode not on a web browser, the JavaScript engine is supposed to do one thing
  2. If in loose mode on a web browser, the JavaScript engine is supposed to do something else
  3. If in strict mode (browser or not), the JavaScript engine is supposed to do yet another thing

The rules for the loose modes are tricky, but in strict mode, function declarations in blocks are easy: They're local to the block (they have block scope, which is also new in ES2015), and they're hoisted to the top of the block. So:

"use strict";
if (someCondition) {
 foo(); // Works just fine
 function foo() {
 }
}
console.log(typeof foo); // "undefined" (`foo` is not in scope here
 // because it's not in the same block)
  • Function Declaration

  • "Anonymous" function Expression (which despite the term, sometimes get names)

  • Named function Expression

  • Accessor Function Initializer (ES5+)

  • Arrow Function Expression (ES2015+)

  • Method Declaration in Object Initializer (ES2015+)

  • Constructor and Method Declarations in class (ES2015+)

Also because it's not part of the step-by-step execution of the code, you can't put it inside a control structure like try, if, switch, while, etc.

if (someCondition) {
 function foo() { // <===== INVALID AND WILL FAIL ON
 } // MANY ENGINES
}

Some engines will handle the above even though it's invalid, by rewriting it as a function expression on-the-fly. There's talk of adding a function statement to the next spec (ECMAScript6) to codify that. But with current engines, it will not work reliably; don't do it.

  • Function Declaration

  • "Anonymous" function Expression (which despite the term, sometimes get names)

  • Named function Expression

  • Accessor Function Initializer (ES5+)

  • Arrow Function Expression (ES2015+)(these are also anonymous in nature, and yet sometimes get names)

  • Method Declaration in Object Initializer (ES2015+)

  • Constructor and Method Declarations in class (ES2015+)

Until ES2015, the spec didn't cover what a JavaScript engine should do if you put a function declaration inside a control structure like try, if, switch, while, etc., like this:

if (someCondition) {
 function foo() { // <===== HERE THERE
 } // <===== BE DRAGONS
}

And since they're processed before step-by-step code is run, it's tricky to know what to do when they're in a control structure.

Although doing this wasn't specified until ES2015, it was an allowable extension to support function declarations in blocks. Unfortunately (and inevitably), different engines did different things.

As of ES2015, the specification says what to do. In fact, it gives three separate things to do:

  1. If in loose mode not on a web browser, the JavaScript engine is supposed to do one thing
  2. If in loose mode on a web browser, the JavaScript engine is supposed to do something else
  3. If in strict mode (browser or not), the JavaScript engine is supposed to do yet another thing

The rules for the loose modes are tricky, but in strict mode, function declarations in blocks are easy: They're local to the block (they have block scope, which is also new in ES2015), and they're hoisted to the top of the block. So:

"use strict";
if (someCondition) {
 foo(); // Works just fine
 function foo() {
 }
}
console.log(typeof foo); // "undefined" (`foo` is not in scope here
 // because it's not in the same block)
Link to official, not draft, ES2015 spec; update terminology; mention method syntax in object initializers
Source Link
T.J. Crowder
  • 1.1m
  • 201
  • 2k
  • 2k
Loading
Added comma to correct syntax, fixed a confusing line of code
Source Link
T.J. Crowder
  • 1.1m
  • 201
  • 2k
  • 2k
Loading
Added comma to correct syntax, removed a confusing line of code
Source Link
Loading
Add further ES5 and ES6 forms
Source Link
T.J. Crowder
  • 1.1m
  • 201
  • 2k
  • 2k
Loading
Bounty Awarded with 200 reputation awarded by Etheryte
edit after the answer was moved
Source Link
T.J. Crowder
  • 1.1m
  • 201
  • 2k
  • 2k
Loading
Post Merged (destination) from stackoverflow.com/questions/22173394/…
added 1914 characters in body
Source Link
T.J. Crowder
  • 1.1m
  • 201
  • 2k
  • 2k
Loading
added 1914 characters in body
Source Link
T.J. Crowder
  • 1.1m
  • 201
  • 2k
  • 2k
Loading
Source Link
T.J. Crowder
  • 1.1m
  • 201
  • 2k
  • 2k
Loading
lang-js

AltStyle によって変換されたページ (->オリジナル) /