03函数的扩展(ES6)

119 阅读4分钟

函数的扩展

1.函数参数的默认值

1.1 参数变量是默认声明的,不能用let或者const再次声明

使用参数的默认值时,函数不能有同名参数

参数默认值是不传值的,而是每次都重新计算默认值表达式的值。(参数默认值是惰性求值的)

let x = 99;

function foo(p = x + 1) {

console.log(p);

}

foo() // 100

x = 100;

foo() // 101

上面代码中,参数p的默认值是x + 1。这时,每次调用函数foo(),都会重新计算x + 1,而不是默认p等于 100

1.2参数默认值与解构赋值的默认值结合使用,函数参数的默认值生效以后,参数解构赋值依然会进行

1.3参数默认值的位置

定义默认值的参数,应该是函数的尾参数,这样可以比较容易看出来到底省略了哪写参数

1.4函数的length属性

指定了默认值以后,函数的length属性就是返回没有指定默认值的参数个数,若是指定了默认值后,length属性将会失真

length属性的含义是该函数预期传入的参数个数,某个参数指定默认值以后,预期传入的参数个数就不包括这个参数,rest参数也不会计入length属性

如果设置了默认值的参数不是尾参数,那么length属性不再计入后面的参数

1.5 作用域

一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域

利用参数默认值可以指定某个参数不得省略,如果省略就抛出一个错误

如果参数已经赋值,默认值中的函数就不会运行,若将参数默认值设为undefined,表明这个参数是可以省略的

2.rest参数

rest参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了

rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中

arguments对象不是数组,而是一个类似数组的对象,所以为了使用数组的方法必须使用Array.from先将其转为数组

// arguments变量的写法 
function sortNumbers() { return Array.from(arguments).sort(); } 
// rest参数的写法 
const sortNumbers = (...numbers) => numbers.sort(); 

rest参数之后不能再有其他参数(即只能是最侯一个参数),否则会报错 函数的length属性,不包括rest参数

3.严格模式 'use strict'

只要函数参数使用了默认值,解构赋值,或者扩展运算符,那么函数内部就不能显示设定为严格模式,否者会报错

规避限制的方法

1.设定全局性的严格模式

'use strict'; function doSomething(a, b = a) { // code }

2.把函数包在一个无参数的立即执行函数里面

const doSomething = (function () { 'use strict'; return function(value = 42) { return value; }; }());

4.name属性

函数的name属性,返回该函数的函数名

如果匿名函数,ES5和ES6的name属性返回的值不一样

如果将一个具名函数赋值给一个变量,ES5和ES6的name属性都会返回这个具名函数原本的名字

Function构造函数返回的函数实例,name属性的值为anonymous

bind返回的函数,name属性值会加上bound前缀

5.箭头函数

允许箭头(=>)定义函数 如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分

如果箭头函数的代码块部分多余一条语句,就要使用大括号将它们括起来,并且使用return语句返回 由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错

如果箭头函数只有一行语句,且不需要返回值,可以采用下面的写法,就不用写大括号了。

let fn = () => void doesNotReturn();

箭头函数可以与变量解构结合使用。

箭头函数的一个用处是简化回调函数。

// 普通函数写法 
[1,2,3].map(function (x) { return x * x; });
// 箭头函数写法
[1,2,3].map(x => x * x); 

【注】

1.箭头函数没有自己的this对象

2.不可以当作构造函数,也就是说不可以对箭头函数使用new命令,否则会抛出一个错误

3.不可以使用arguments对象,该对象在函数题内不存在,如果要用,可以用rest参数替代

4.不可以使用yield命令,因为箭头函数不能用作Generator函数

不适用场合:

1.定义对象的方法,且该方法内部包括

this const cat = { lives: 9, jumps: () => { this.lives--; } } 

如果写成上面那样的箭头函数,使得this指向全局对象,因此不会得到预期结果。这是因为对象不构成单独的作用域,导致jumps箭头函数定义时的作用域就是全局作用域。

2.需要动态的this的时候,也不应该使用箭头函数