ES6-learning-函数的扩展

1.ES6允许参数设置默认值(参数默认值不是传值的,而是每次都重新计算默认值表达式的值-参数默认值是惰性求值的)

let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101

2.参数默认声明,不能用Let或const再次声明
3.使用参数默认值时,函数不能有同名参数

练习:
// 写法一
function m1({x = 0, y = 0} = {}) {
  return [x, y];
}

// 写法二
function m2({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}

区别:
写法一函数参数的默认值是空对象,但是设置了对象解构赋值的默认值,写法二函数参数的默认值是一个有具体属性的对象,但是没有设置对象解构赋值的默认值

函数的length属性
指定默认值后,函数的length属性,将返回没有指定默认值的参数个数,即指定了默认值后,length属性将失真

(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2

4.箭头函数
使用注意点:1)函数体内的this对象,是定义时所在对象,而不是使用时所在对象(this对象的指向是固定的---原因:箭头函数根本没有自己的this,导致内部的this就是
             外层代码看的this,也是没有this,所以就不能用作构造函数)
            2)不可以当作构造函数,不可以使用new命令,否则会抛出一个错误
            3)不可以使用arguments对象,该对象在函数体内不存在,如果要用,可以用rest参数代替
            4)不可以使用yield命令,因此箭头函数不能用作Generator函数

5.函数绑定运算符::
双冒号左边是一个对象,右边是一个函数,该运算符会自动将左边的对象,作为上下文环境,绑定到右边的函数上面。
6.尾调用:某个函数最后一步是调用另一个函数(不一定出现在函数尾部,只要是最后一步操作即可)
  1)调用帧:保存调用位置和内部变量等信息。如果在函数A的内部调用函数B,那么在A的调用帧上方,还会形成一个B的调用帧。等到B运行结束,将结果返回到A。B的
调用帧才会消失,如果函数B内部还调用函数C,那就还有一个C的调用帧,以此类推,所有的调用帧,就形成一个调用栈
     严格模式----尾调用优化:只保留内层函数的调用帧,如果所有函数都是尾调用,那么完全可以做到每次执行时,调用帧只有一项,大大节省内存。(只有不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,否则就无法进行
“尾调用优化”)
     普通模式----func.arguments:返回调用时函数的参数。。。。。。func.caller返回调用当前函数的那个函数
7.尾递归:原来的递归容易调用栈溢出

 1)蹦床函数可以将递归执行转为循环执行

function trampoline(f) {
 	 while (f && f instanceof Function) {
   	 f = f();
 	 }
 	 return f;
	}

2)尾递归优化

function tco(f) {
  	var value;
  	var active = false;
  	var accumulated = [];

 	 return function accumulator() {
    	accumulated.push(arguments);
    	if (!active) {
      	active = true;
      	while (accumulated.length) {
        value = f.apply(this, accumulated.shift());
      	}
      	active = false;
      	return value;
   	 }
 	 };
	}

	var sum = tco(function(x, y) {
  	if (y > 0) {	
	return sum(x + 1, y - 1)
 	 }
  	else {
    	return x
 	 }
	});

	sum(1, 100000)
	// 100001

tco函数是尾递归优化的实现,它的奥妙就在于状态变量active。默认情况下,这个变量是不激活的。一旦进入尾递归优化的过程,这个变量就激活了。
然后,每一轮递归sum返回的都是undefined,所以就避免了递归执行;而accumulated数组存放每一轮sum执行的参数,总是有值的,这就保证了accumulator函数内部
的while循环总是会执行。这样就很巧妙地将“递归”改成了“循环”,而后一轮的参数会取代前一轮的参数,保证了调用栈只有一层。

8.ES2017尾部逗号:可为函数添加第多个参数,或者调整参数的次序。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值