ES6入门三 - 函数扩展

1. 函数参数的默认值

在ES6中,函数的参数可用设置默认值,即直接卸载参数定义的后面。通常与结构赋值结合使用。

 			function f({x,y=5}={}){
				console.log(x,y);
			}
			f({});//undefined 5
			f({x:1});//1 5
			f({x:1,y:2});//1 2
			f(); undefined 5

使用默认值的参数应该在无默认值参数的后面定义,因为在函数使用时会根据参数顺序传参,除非显示输入undefined,但null不会触发默认参数。

			function f(x=5,y){
				console.log(x,y);
			}
			f(2,3);//2 3
			f(1);//1 undefined
			f(undefined,3);//5 3
			f(null);//null undefined

			function fn(y,x=5){
				console.log(y,x);
			}
			fn(2,3);//2 3
			fn(1);//1 5
			

函数的length属性:
表示该函数预期传入的参数个数。
length属性的返回值,等于函数的参数个数减去指定了默认值的参数个数。
如果有默认值参数不是尾参数,length属性也不会再计入后面无默认值参数的个数。
length属性不包括rest参数。

			console.log((function f(a,b,c,d,e){}).length);	//5		
			console.log((function f(a,b,c=3,d=4,e=5){}).length);//2
			console.log((function f(a=2,b,c,d,e){}).length);//0
			console.log((function(a,b ,...c) {}).length);//2

有默认值参数的作用域:
有默认值参数的函数进行声明初始化时,参数会形成一个单独的作用域,初始化结束时,该作用域就会消失。当默认值是变量时,会依次往上查找,如果未找到变量的定义,就会报错。

/* 			var x=1;
			function f(x,y=x){
				console.log(x,y);
			}
			f(2);//2 2 */
			
/* 			let x=1
			function f(y=x){
				//let x=2;
				console.log(x,y);
			}
			f();//1 1
			f(2);//1 2 */
			
 			function f(y=x){
				let x=1;
				console.log(x,y);
			} 
			f(2);//1 2
			f();//Uncaught ReferenceError: x is not defined

应用:指定参数不能省略,或者给参数添加限定

			function throwError(){
				throw new Error("Missing parameter ");
			}
			function f(para=throwError()){
				console.log(para);
			}
			f(1);//1
			f();//Uncaught Error: Missing parameter 

当函数作为值时,加了圆括号表示运行时执行,没有表示定义时执行。

2.rest参数

rest参数用于获取函数多余的参数,该参数是一个数组,多余参数都在数组中。
rest参数必须是最后一个参数,否则会报错。

		function add(...numbers){//求和函数
				let sum=0;
				for(let n of numbers){
					sum+=n;
				}
				console.log(sum);
			}
			add(1,2,3,4,5);//15
			
			function fn(array,...items){
				items.forEach(function(item){
					array.push(item);
					console.log(item);
				});
				console.log(array);
			}
			var a=[];
			fn(a,1,2,3);//1 2 3
			
 			function f(a,...b ,c) {				
			};//Uncaught SyntaxError: Rest parameter must be last formal parameter

ES6规定只要函数参数使用了默认值、结构赋值、或者扩展原酸符,那么函数内部就不能显示设定为严格模式,否则会报错。


3.箭头函数

ES6允许使用箭头(=> )定义函数

			//箭头函数
			let f=(v1,v2)=>{return v1+v2;};
			//等同于标准形式
			let fn=function (v1,v2){
				return v1+v2;
			};
			console.log(f(1,2));//3
			console.log(fn(1,2));//3		

圆括号内表示参数部分,多个参数无参数必须使用圆括号;大括号内放代码块,多行代码必须使用大括号。

箭头函数的特殊形式:
如果是单一变量,参数部分可以省略圆括号;如果直接返回结果,可以省略大括号和return关键字 。

			let f=v=>v;
			//等同于
			let fn=function (v){
				return v;
			}
			console.log(f(1));//1
			console.log(fn(1));//1
			
			let fun=(num1,num2)=>num1+num2;
			//等同于
			let func=function (num1,num2){
				return num1+num2;
			}
			console.log(fun(1,2));//3
			console.log(func(1,2));//3	

			let fun=()=>{return 5;};
			console.log(fun());//5		

如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

			let f=name=>({name:name,sex:"男"});
			console.log(f("名字"));
			
			let fn=name=>{name:name,sex:"男"};//报错Uncaught SyntaxError

如果箭头函数只有一行语句,且不需要返回值,可以直接声明。

let fn = () => void doesNotReturn();//不知道为什么使用该方法报错
//Uncaught ReferenceError: doesNotReturn is not defined

搭配rest参数使用。

			let f=(...values)=>values;
			console.log(f(1,2,3,4,5));//[1, 2, 3, 4, 5]
			let fn=(head,...values)=>[head,values];
			console.log(fn(1,2,3,4,5));//[1,[2, 3, 4, 5]]	

箭头函数使用注意:
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。箭头函数可以让this指向固定化,这种特性很有利于封装回调函数。
除了this,arguments、super、new.target变量在箭头函数之中也是不存在的,指向外层函数的对应变量。

// ES6
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}
// 等同于ES5
function foo() {
  var _this = this;
  setTimeout(function () {
    console.log('id:', _this.id);
  }, 100);
}

(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

函数的尾调用

某个函数的最后一步是调用另一个函数。尾调用的另一个函数不能执行其他操作。尾调用不一定出现在函数尾部,只要是最后一步操作即可。
尾调用优化能大大降低“调用帧”,节省内存空间。

函数调用会在内存形成一个“调用记录”,又称“调用帧”(call frame),保存调用位置和内部变量等信息。如果在函数A的内部调用函数B,那么在A的调用帧上方,还会形成一个B的调用帧。等到B运行结束,将结果返回到A,B的调用帧才会消失。如果函数B内部还调用函数C,那就还有一个C的调用帧,以此类推。所有的调用帧,就形成一个“调用栈”(call stack)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值