ES6------函数扩展

一,ES6的参数默认值

1.在es5中并没有实现函数的参数默认值,而ES6实现了这部分功能,使函数的参数默认值书写更为简洁,直观。

{
	function defalutArg(name='max',age=21)
	{
	  let info = name + ' is ' + age +' years old';
	  return info
	}
	console.log(defalutArg('miko')) // miko is 21 years old
	console.log(defalutArg('jim',30)) // jim is 30 years old
} 

2.函数参数默认值可以是任何合理的表达式,且每次调用都会重新计算默认值表达式的值。

{
	let n=100
	function addY(x=0,y=n+1)
	{	
		return x+y+n
	}
	console.log(addY(10)) // 211
	n=90
	console.log(addY(10)) //201
}

3.可以使用解构赋值为参数设置默认值。

{
	function introduce({name,age,id}={name:'max',age:21,id:1})
	{
		let introTemplate =`${id}: my name is ${name},i am ${age} years old.`
		let info = introTemplate;
		return info
	}
	console.log(introduce())  // 1: my name is max,i am 21 years old.
}

二,rest参数

1.rest 参数接受函数的多余参数,组成一个数组,放在形参的最后,形式为...arg。注意rest参数后不能在有形参,即rest参数要放在最后面,否则会报错。

{
	function intro(name,age,...details)
	{
		return details 
	}
	console.log(intro('lin',23,'male','china'))	 // ["male", "china"]
	
	function err(name,...details,age)
	{
		return details 
	}
	console.log(err('lin',23,'male','china')) //Rest parameter must be last formal parameter
}

2.rest参数和arguments的区别:
arguments包含传入的所有参数,rest参数只包含没有直接声明的参数
arguments是一个类数组对象,而rest参数是一个真正的数组,可以使用数组的所有方法。
函数的length属性,不包含rest参数

3.rest参数可以被结构化,类似于数组的解构赋值

{
	function f(...[a, b, c]) {  
	  return a + b + c;  
	}  
	  
	f(1)          //NaN 因为只传递一个值,b 和 c = undefined
	f(1, 2, 3)    // 6  
	f(1, 2, 3, 4) // 6 (第四值没有与之对应的变量名)
}

三,箭头函数

1.ES6标准新增了一种新的函数:箭头函数,也称“胖箭头函数”, 允许使用“箭头”(=>)定义函数,是一种简写的函数表达式。

2.箭头函数的形式

//  一个参数对应一个表达式
param => expression;// 例如 x => x+2;

// 多个参数对应一个表达式
(param [, param]) => expression; //例如 (x,y) => (x + y);

// 一个参数对应多个表示式
param => {statements;} //例如 x = > { x++; return x;};

//  多个参数对应多个表达式
([param] [, param]) => {statements} // 例如 (x,y) => { x++;y++;return x*y;};

//表达式里没有参数
() => expression; //例如var flag = (() => 2)(); flag等于2

() => {statements;} //例如 var flag = (() => {return 1;})(); flag就等于1

 //传入一个表达式,返回一个对象
([param]) => ({ key: value });
//例如  var fuc = (x) => ({key:x})
        var object = fuc(1);
        alert(object);//{key:1}

3.箭头函数的性质特点
(1)箭头函数本身没有this,当在箭头函数使用了this对象,该this对象是父作用域的this对象,和调用方式无关且要注意,箭头函数的this是被定义时处于的上下文的this,而不是箭头函数被调用时处于的上下文

{
	let cat={
			name:'nancy',
			sex:'female',
			voice:'maoomaoo',
			catVoice:()=>this.voice		
		}
	console.log(cat.catVoice()) //undefined catVoice的父作用域为块作用域。块作用域的this指向window
}
{
	let cat={
		name:'nancy',
		sex:'female',
		voice:'maoomaoo',
		catVoice:function()
		{
			let f = ()=>this.voice
			return f()
		}
	}
	console.log(cat.catVoice())  // 'maoomaoo'
	let fn=cat.catVoice
	console.log(fn()) // 'undefined'
}

执行cat.catVoice()时,箭头函数f的父作用域是函数catVoice的函数作用域,catVoice函数通过对象的方法被调用,所以catVoice函数的this指向当前对象cat, 因此箭头函数的this也指向cat,最后返回'maoomaoo'

当执行fn()时,catVoice函数被裸调用,因此catVoicethis指向全局对象window,fthis对象随即指向window,所以返回undefined

总结,箭头函数的this指向由父作用域的this指向决定

(2)箭头函数没有arguments关键字,要想接受不定参数,需使用rest参数。

{
	let fn =(...[a,b,c])=>a+b+c
	console.log(fn(1,2,3,4)) // 6
}

(3)箭头函数没有原型属性

{
	let add = (x,y)=>x+y
	console.log(add.prototype) // undefined
}

(4) 箭头函数不能作为构造函数,也没有new操作,因为箭头函数都没有this,

四,尾调用(Tail Call)

1.尾调用用一句话说就是某个函数的最后一步操作是调用一个函数,则称为尾调用


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

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

//情况三
function f(x){
  return g(x);
}

情况一和情况二都不是尾调用,情况三属于尾调用。

2.尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用记录,因为调用位置、内部变量等信息都不会再用到了,只要直接用内层函数的调用记录,取代外层函数的调用记录就可以了。如果所有函数都是尾调用,那么完全可以做到每次执行时,调用记录只有一项,这将大大节省内存。我们称之为尾调用优化。

3.在ES6的严格模式下,才有尾调用优化。

参考
https://segmentfault.com/a/1190000019102902
https://www.cnblogs.com/mengff/p/9656486.html
http://www.ruanyifeng.com/blog/2015/04/tail-call.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值