ES6----函数

本文主要总结ES6新增的函数的用法及注意点。

函数参数默认值

ES6允许为函数参数设置默认值。用法如下:

function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
复制代码

这样写的好处是:

  • 比ES5写法简洁
  • 便于阅读代码
  • 有利于代码优化

需要注意的点:

  • 参数变量是默认声明的,所以不能用let和const再次声明。但是var是可以的。
  • 使用参数默认值时,函数不能有同名参数。
  • 参数默认值是惰性求值的。
  • 有默认值的参数最好放到后面,如果放到前面,传参无法省略;若要使用默认值,需要显示传undefined才会触发默认值
  • 函数的length属性返回没有指定默认值的参数个数。而且如果设置的默认值不是尾参数,那么length属性不再计入后面的参数。
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1
复制代码

rest参数

rest参数的引入,用于获取函数的多余参数,这样就不需要使用arguments对象了。

function push(array, ...items) {
  items.forEach(function(item) {
    array.push(item);
    console.log(item);
  });
}

var a = [];
push(a, 1, 2, 3)
复制代码

需要注意的点:

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

严格模式

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

  • 设置全局性的严格模式
'use strict';

function doSomething(a, b = a) {
  // code
}
复制代码
  • 把函数包裹在一个无参数的立即执行函数里
const doSomething = (function () {
  'use strict';
  return function(value = 42) {
    return value;
  };
}());
复制代码

name属性

函数的那么属性,返回函数的函数名。 需要注意的点:

  • 将匿名函数赋值给一个变量,ES5的name属性返回空字符串,ES6的name属性返回实际的函数名。
var f = function () {};

// ES5
f.name // ""

// ES6
f.name // "f"
复制代码
  • Function构造函数返回的函数实例,name属性的值为anonymous。
(new Function).name // "anonymous"
复制代码
  • bind返回的函数,name属性值会加上bound前缀。
function foo() {};
foo.bind({}).name // "bound foo"

(function(){}).bind({}).name // "bound "
复制代码

箭头函数

用法很简单,主要记录一下需要注意的点。

  • 如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
// 报错
let getTempItem = id => { id: id, name: "Temp" };

// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });
复制代码
  • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42
复制代码

箭头函数的这个特点,使得this指向固定化。根本原因是箭头函数根本没有自己的this,导致内部的this就是外层代码的this。

  • 不可以当做构造函数使用,即不可以使用new命令,否则会抛出错误。因为箭头函数实际上没有this!!!
  • 不可以使用arguments对象,在箭头函数内部该对象不存在。如果要用,可以使用rest参数代替。
  • 不可以使用yield命令,因此箭头函数不能用作Generator函数。
  • 箭头函数内部不存在arguments、super、new.target对象

尾调用优化

尾调用指的是某个函数的最后一步是调用另一个函数。尾调用不一定出现在函数尾部,只要是最后一步操作即可。

function f(x) {
  if (x > 0) {
    return m(x)
  }
  return n(x);
}
复制代码

上面就是一个尾调用的例子。 同时,下面的几种情况不是尾调用。

// 情况一
function f(x){
  let y = g(x);
  return y;
}

// 情况二
function f(x){
  return g(x) + 1;
}

// 情况三
function f(x){
  g(x);
}
复制代码

由于函数内部调用另一个函数,会形成一个调用栈。而尾调用是函数的最后一步操作,所以尾调用的时候不需要保留外层函数的调用帧。直接用内层函数的调用帧就可以。这就是尾调用优化。

由此可知,我们把函数都写成尾调用,使得每次执行时,调用帧只有一项,这会大大节省内存。

但是需要注意一点:

  • 只有不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,否则无法进行尾调用优化。
  • 尾递归优化和它类似。
  • ES6的尾调用优化只在严格模式下开启,正常模式无效。

转载于:https://juejin.im/post/5a375d80f265da43215422ee

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值