深入理解ES6之函数的箭头函数、不定参数、尾调用等

函数是所有编程语言的重要组成部分。

深入理解ES6之函数章节

  • 函数形参的默认值
    • 处理无命名参数
      • 明确函数的多重用途
  • 箭头函数
    • 尾调用优化

函数形参的默认值

在ES5中模拟默认参数。

<script>
			function makeRequest(url,timeout,callback){
				timeout = timeout || 2000;
				callback = callback || function(){}
				// 函数其余部分
			}
</script>

这个方法呢也有一定的缺陷,如果我们想给makeRequest函数的第二个形参timeout传值0时,会被认为是一个假值,并最终将timeout赋值为2000.在这种情况下,可以通过typeof来检查参数类型。
即代码:

<script>
			function makeRequest(url,timeout,callback){
				timeout = (typeof timeout!=="undefined") ?timeout: 2000;
				callback = (typeof callback !== "undefined") ? callback :function(){}
				// 函数其余部分
			}
</script>

ES6中模拟默认参数

<script>
		function makeRequest(url,timeout=2000,callback = function(){}){				
				// 函数其余部分
			}
</script>

url是必须的,其他两个为可选参数。

处理无命名参数

使用无命名参数可以合理的减少代码量
ES5中无命名参数
javaScript提供auguments对象来检查函数的所有参数,而不必定义每一个参数。

<script>
			function pick(object){
				let result = object.create(null);
				// 从第二个参数开始
				for(let i= 1,len=arguments.length;i<len;i++){
					result[arguments[i]] = object[arguments[i]];
				}
				return result;
			}
			let book = {
				title:"living",
				author:"YuHua",
				year:2015
			};
			let bookData = pick(book,"author","year");
			console.log(bookData.author);
			console.log(bookData.year);
</script>

输出结果为

living  YuHua

这个函数模仿了Underscore,js库中的pick()方法,返回一个给定对象的副本,包含原始对象属性的特定子集。
关于pick()函数应该注意如下几点:
1.并不容易发现这个函数可以接受任意数量的参数;
2.因为第一个参数为命名参数且被使用,当你查找需要拷贝的属性名称时,不得不从索引1开始遍历arguments对象
所有在es6中引入不定参数
不定参数
该参数为一个数组,包含着自它之后传入的所有参数,通过这个数组名即可逐一访问里面的参数。

function pick(object,...keys){
	let result = Object.create(null);
	for(let i= 0,len=keys.length;i<len;i++){
		result[keys[i]] = object[keys[i]];
	}
	return result;
}

不定参数keys包含的时object之后传入的所有参数,而arguments对象包含的则是所有传入的参数,包含Object。

不定参数使用限制

  1. 每个函数最多只能声明一个不定参数,而且不定参数一定要放在参数的末尾。
//抛出异常 不定参数后不能有其他命名参数
 <script>
	function pick(object,...keys,last){
		let result = Object.create(null);
		for(let i= 0,len=keys.length;i<len;i++){
			result[keys[i]] = object[keys[i]];
		}
		return result;
	}
</script>
  1. 不定参数不能用于对象字面量setter之中。
let object = {
	//语法错误 不可以在setter中使用不定参数
	set.name(...value)
	//其余代码
}

是因为对象字面量setter的参数有且只能有一个。

不定参数对arguments的限制
如果声明函数时定义了不定义参数,则在函数被调用时,arguments对象包含了所有传入函数的参数。
无论是否使用不定参数,arguments对象总是包含所有传入函数的参数。

增强的Function构造函数
通常用来动态创建新的函数,这种构造函数接受字符串形式的参数,分别为参数和函数体。

let object = {
	//语法错误 不可以在setter中使用不定参数
	set.name(...value)
	//其余代码
}

var pickFirst = new Function("...args","return args[0]");
console.log(pickFirst(1,2));//1

展开运算符
Math.max()是Javascript内置的返回最大值的函数。
它不允许传入数组,所以在ES5中需要手动实现数组遍历取值,或者使用apply方法。

let values = [25,50,75,100];
console.log(Math.max.apply(Math,values)); //100

在ES6中使用展开运算符就可以实现对数组的访问。

let values = [25,50,75,100];
console.log(Math.max(...values)); //100

使用apply方法需要手动指定this的绑定,使用展开运算符就会使代码更简洁。

name属性
函数name属性的值不一定引用同名变量,它只是协助调试用的额外信息,所以不能使用name属性的值来获取对于函数的引用。

明确函数的多重用途

JavaScript函数有两个不同的内部方法:[[call]]和[[construct]]。当通过new关键字调用函数时,执行的是[[construct]]函数,它负责创建一个通常被称作实例的新对象,然后再执行函数体,将this绑定到实例上,如果不通过new关键字调用,则执行[[call]]函数,从而直接执行代码的函数体。
具有[[construct]]方法的函数被统称为构造函数。
箭头函数就没有[[construct]]方法。

元属性New,target
为了解决判断函数是否通过new关键字调用的问题,,ES6引入了new.target这个元属性。指非对象属性,可以提供非对象目标的补充信息,例如new。
如果调用[[construct]]方法,new.target被赋值为new操作符的目标,通常是新创建对象实例,也就是函数体内this的构造函数;如果调用[[call]]方法,则new.target的值为undefined。

在函数外使用New.target是一个错误的语法。

箭头函数

箭头函数的极大特点:

  • 没有this、super、arguments和new.target绑定,他们由外围最近一层非箭头函数决定。
  • 不能通过New关键字调用。箭头函数没有[[construct]]方法,所以不能用作构造函数。
  • 没有原型,所以不存在prototype属性;
  • 不可以改变this绑定,函数内部的this值不可以被改变,在函数生命周期内始终保持一致。
  • 不支持arguments对象,箭头函数没有arguments绑定,所以必须通过命名参数不定参数两种形势访问函数的参数。
  • 不支持重复命名参数,传统函数只有在严格模式下才不能有重复命名的参数。
    可以用箭头函数写一个排序的比较器:
var result = values.sort((a,b)=>a-b);

尾调用优化

尾调用优化是指函数作为另一个函数的最后一条语句被调用,

function doSomething(){
     return doSomethingElse();//尾调用
}

在ES6中如果满足以下条件,尾调用不再创建新的栈帧,而是清楚并重要当前栈帧。(因为在ES5之前需要)

  • 尾调用不访问当前栈帧的变量(也就是说函数不一定是个闭包)
  • 再函数内部,尾调用是最后一条语句
  • 尾调用的结果作为函数值返回。
    好处:
    尾调用可以帮助函数保持一个更小的调用栈,从而减少内存的使用,避免栈溢出错误,当程序满足条件时,引擎会自动对其优化。
function factorial(n,p=1){
	if(n<=1){
		return 1*p;
	}else{
		let result = n*p;
		//优化后
		return factorial(n-1,result)}
}

你可能感兴趣的:(ES6)