1. Default values for function parameters
Basic Usage
Before ES6, you can't directly specify default values for function parameters. You can only use flexible methods.
function log(x, y){ y = y || 'world' console.log(x,y) } log('hello') //hello world log('hello', 'china') //hello china log('hello', '') //hello world
ES6 allows you to set default values for function parameters, that is, write them directly after the parameter definition
function log(x, y = 'world'){ console.log(x, y) } log('hello') //hello world log('hello', 'china') //hello china log('hello', '') //hello
Note: parameter variables are declared by default. In the function body, let or const cannot be used to declare again, otherwise an error will be reported. When using default parameters, the function cannot have parameters with the same name.
Used in conjunction with deconstruction assignment defaults
The default value of the parameter can be used in combination with the default value of the deconstruction assignment
function foo({x, y = 5}){ console.log(x, y) } foo({}) //undefined 5 foo({x: 1 }) //1 5 foo({x: 1, y: 2}) //1 2 foo() //report errors function foo2({x, y = 5} = {}){ console.log(x, y) } foo() //undefined 5
The location of the default value of the parameter
Generally, the parameter with the default value defined should be the tail parameter of the function. Because it is easier to see which parameters are omitted. If the non tail parameter is set to the default value, in fact, this parameter cannot be omitted.
function fn(x = 1, y){ return [x, y] } fn() //[1, undefined] fn(2) //[2, undefined] fn(, 1) //report errors fn(undefined, 1) //[1,1]
The length attribute of the function
After the default value is specified, the length property of the function will return the number of parameters without the specified default value. If the default value is encountered, the return length will be stopped directly, that is, the number of parameters before the default value appears for the first time
(function(a) {}).length //1 (function(a = 5) {}).length //0 (function(a,b,c = 5) {}).length //2
Scope
Once the default value of the parameter is set, the parameter will form a separate context when the function is declared and initialized. After initialization, the scope will disappear. This syntax behavior will not appear when the parameter default value is not set.
var x = 1 function fn(x, y = x){ console.log(y) } fn(2) //2
Explanation: the default value of parameter y is equal to variable x. When the function fn is called, the parameters form a separate scope. The default value of X is in the scope of the global variable, instead of the default value of X
Let's look at the following example:
let x = 1 function fn(y = x){ let x = 2 console.log(y) } fn() //1
Explanation: when calling a function, the parameter y = x forms a separate scope. In this scope, the variable x itself is not defined, so it points to the outer global variable x. When calling a function, the local variable x inside the function body cannot affect the default value variable x. if the global variable X does not exist at this time, an error will be reported.
2. rest parameter
ES6 introduces the rest parameter (in the form of... Variable name) to obtain the redundant parameters of the function, so there is no need to use the arguments object. The variable matched with rest parameter is an array, which puts redundant parameters into the array (actually the inverse operation of extension operator)
function add(...val){ let sum = 0 for(var v of val){ sum += v } return sum } add(2,5,3) //10
The arguments object is not an array, but an array like object, so in order to use the array method, you must use array prototype. slice. Call first converts it into an array. The rest parameter does not have this problem. It is a real array.
3. Strict mode
Starting from ES5, the internal function can be set to strict mode
function todo(a,b){ 'use strict' //... }
ES6 has made some modifications to stipulate that as long as the function parameters use default values, deconstruction assignment, or extension operators, the internal display of the function cannot be set to strict mode, otherwise an error will be reported
//report errors function todo (a, b, c = 1){ use 'strict' //... }
4. name attribute
The name attribute of the function returns the function name of the function
function foo() {} foo.name // 'foo'
Note that ES6 has made some modifications to the behavior of this attribute. If an anonymous function is assigned to a variable, the name attribute of ES5 will return an empty string, while the name attribute of ES6 will return the actual function name
var fn = function () {} //es5 fn.name // '' //es6 fn.name // 'fn'
If a named function is assigned to a variable, the name properties of ES5 and ES6 will return the original name of the named function
const bar = function baz() {} //es5 bar.name // 'baz' //es6 bar.name // 'baz'
The Function instance returned by the Function constructor. The value of the name attribute is anonymous
(new Function).name //'anonymous'
For the function returned by bind, the value of the name attribute will be prefixed with bound
function foo () {} foo.bind({}).name // 'bound foo' (function(){}).bind({}).name // 'bound'
5. Arrow function
Basic Usage
ES6 allows functions to be defined using "arrows" (= >)
var fn = val => val //Equivalent to var fn = function(val){ return val }
If the arrow function does not require parameters or requires more than one parameter, a parenthesis is used to represent the parameter part
var fn = () => 5 //Equivalent to var fn = function() { return 5 } var sum = (num1, num2) => num1 + num2 //Equivalent to var sum = function(num1,num2){ return num1 + num2 }
If the code block of the arrow function is more than one statement, you need to enclose them in curly braces
var fn = (a,b) { if(a>b){ return a }else{ return b } }
Since braces are interpreted as code blocks, if the arrow function directly returns an object, you must add parentheses outside the object, otherwise an error will be reported
//report errors let getTem = id => { id: id, name: 'Temp' } //No error reporting let getTem = id => ({ id: id, name: 'Temp' })
Precautions for use
The arrow function consists of several points for attention:
(1) this object in the function body is the object where the arrow function is defined, not the object where it is used
(2) It cannot be used as a constructor, that is, it cannot use the new command, otherwise an error will be reported
(3) The arguments object cannot be used. The arguments object inside the arrow function does not save arguments. You can use the rest parameter instead
(4) You cannot use the yield command, so the arrow function cannot be used as a Generator function
6. Tail call optimization
What is a tail call?
Tail Call is an important concept of functional programming, which means that the last step of a function is to call another function
function fn(x){ return gn(x) }
In the above code, the last step of function fn is to call function gn, which is called tail call
Tail call optimization
Note that only when the internal variables of the outer function are no longer used, the call frame of the inner function will replace the call frame of the outer function, otherwise the tail call optimization will not be possible
function addone(a){ var one = 1 function inner(b){ return b + one } return inner(a) }