1. Define a regular anonymous function syntax:
function (x) { return x * x; }
Use the arrow 2. This function can use the function to get only one line of code!
x => x * x
Anonymous function equivalent to the function of the arrow, and simplifies the function definition.
Arrow function has two formats:
- Kind of like the above, it contains only an expression, even
{
... }
andreturn
are omitted. - Another may contain multiple statements, this time can not be omitted
{ ... }
andreturn。
E.g:
x => { if (x > 0) { return x * x; } else { return - x * x; } }
Arrow function syntax rules:
(parameters) => { statements }
If no function has a plurality of parameters or parameter, can be written as follows:
If the return value has only one expression (expression), the braces may be omitted.
// no parameters: () => 3.14 // parameter // If only one parameter may be omitted parentheses: X => X * X @ two parameters: (X, Y) => X * X + Y * Y // variable parameters: (X, Y, ... REST) => { var I, SUM = X + Y; for (I = 0; I <rest.length; I ++ ) { SUM + = REST [I ]; } return SUM; }
Note: If you want to return an object, we should note that if a single expression, so write it will complain:
// SyntaxError: x => { foo: x }
Because the body functions and {...} syntax conflict, it should be changed to:
// ok: x => ({ foo: x })
This is not bound local
Arrow function appears to be a shorthand anonymous function, but in fact, arrow functions and anonymous functions have a clear distinction: the internal function of the arrow this
is lexical scope is determined by the context. Arrow function does not bind this
. Arrow function or said that will not change the this
original binding.
E.g
function Counter() { this.num = 0; } var a = new Counter(); console.log(a.num);// 0
Because the use of keywords new construction, Count () function in this bind to a new object, and assigned to a
. By console.log print a.num, will output 0.
If we want every passing second the value a.num plus 1, how to achieve it? You can use setInterval () function.
function Counter() { this.num = 0; this.timer = setInterval(function add() { this.num++; console.log(this.num); }, 1000); } var b = new Counter(); // NaN // NaN // NaN // ...
Every second, there will be a NaN
print out, rather than numbers accumulated.
Reasons: First, the function setInterval is not called the object of a declaration, did not use the new keyword, then there is no use of the bind, Call and apply. setInterval just an ordinary function. In fact setInterval inside of this is bound to the global object.
The reason why the print NaN, because this.num bound to the window object num, and window.num undefined.
Solution: Use the arrow function! Use the arrow function will not cause this is bound to the global object.
function Counter() { this.num = 0; this.timer = setInterval(() => { this.num++; console.log(this.num); }, 1000); } var b = new Counter(); // 1 // 2 // 3 // ...
By Counter constructor bound this will be retained. In setInterval function, the this still point to our newly created b
object.
Another example:
Since the JavaScript function on the error handling this binding, the following example can not get the expected results:
var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = function () { return new Date().getFullYear() - this.birth; // this指向window或undefined }; return fn(); } };
Now, fully restored the function of the arrow pointing to this is, this always points to lexical scoping, which is the outer layer of the caller obj:
var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象 return fn(); } }; obj.getAge(); // 25
If you use the arrow functions, before the kind of hack writing:
var that = this;
It is no longer needed.
Since this
the arrow function is already bound in accordance with lexical scope, therefore, use call () or ) when you call the function of the arrow, not for the Apply ( the this bound, that is passed in the first argument is ignored:
var obj = { birth: 1990, getAge: function (year) { var b = this.birth; // 1990 var fn = (y) => y - this.birth; // this.birth仍是1990 return fn.call({birth:2000}, year); } }; obj.getAge(2015); // 25