ES6学籍(四)

本文围绕ES6函数展开,介绍了函数参数默认值的基本用法、length属性和作用域,还提及rest参数、严格模式和name属性。重点讲解了箭头函数的用法、注意事项及嵌套情况,以及绑定this的方法。此外,详细阐述了尾调用优化,包括尾调用、尾递归概念,递归函数改写和尾递归优化的实现。

函数

函数参数的默认值

基本用法

ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。

function log(x,y='World'){
	console.log(x,y) //赋值什么的与解构赋值的一样
}
复制代码

函数的length属性

指定了默认以后,函数的length属性将返回没有指定默认值得参数个数。如果设置了默认参数length返回的就是0

作用域

一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。等到初始化结束,这个作用域就会消失

rest

ES6引入了rest参数(形式为”...变量名“),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配 的变量是一个数组,该变量将多余的参数放入其中。

function add(...values){
	let sum = 0
	for (var val of values){
		sum += val
	}
	return sum
}
add(2,3,5) // 10
复制代码

rest 参数之后不能再有其它参数(即只能是最后一个参数),否则会报错

严格模式

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

function doSomething(a,b=a){
	'use strict' //使用严格模式
}// 会报错
复制代码

解决这个的两种办法时我们可以使用以下方式:

  • 第一种是设定全局性的严格模式
'use strict'
function doSomething(a,b=a){
//code
}
复制代码
  • 第二种是把函数包在一个无参数的立即执行函数里面
const doSomething = (function(){
	'use strict'
	return function(value = 42) {
		return value
	}
})
复制代码

name属性

函数的name属性返回改函数的函数名

function foo(){}
foo.name // 'foo'
var f = function(){}
// ES5 
f.name // ''
//ES6
f.name //'f'
复制代码

如果将一个具名函数赋值给了一个变量,ES5和ES6的name属性都返回这个具名函数原本的名字

剪头函数

基本用法

ES6允许使用‘剪头’(=>)定义函数

var f = v => v 
// 完整写法
var f = function(v){
	return v
}
复制代码

如果剪头函数不需要参数活需要多个参数,就使用圆括号代表参数部分。

var f = () => 5
复制代码

注意事项

剪头函数有以下几个使用注意事项

  • 函数体内的this对象就是定义时所在的对象,而不是使用时所在的对象。
  • 不可以当做构造函数。也就是说,不能使用new命令,否则会抛出错误。
  • 不可以使用arguments对象,该对象在函数体内不存在。如果需要用,可以用rest参数代替。
  • 不可以使用yield命令,因此箭头函数不能用做Generator函数。

箭头函数嵌套

es5
function  insert(value)  {
	return  {into:function  (array)  {
		return  {after:function  (afterValue)  {
			array.splice(array.indexOf(afterValue)  + 1, 0,  value );// splice(要替换的位置,0为添加其它为删除的位数,要替换的值)
			return  array ;
		}} ;
	}} ;
}
insert(2) . into([l ,  3)) . after(l) ;  //[1 ,  2, 3)
复制代码
箭头函数
let insert = (value) =>
 ({into: (array) =>
	({after: (afterValue) => {
		  array.splice(array.indexOf(afterValue) + 1, 0, value)
		  return array
		}
	})
})
insert(2) . into([l ,  3)) . after(l) ;  //[1 ,  2, 3)
复制代码

绑定this

箭头函数可以绑定this对象,大大减少了显式绑定this对象的写法(call、apply、bind), (针对箭头函数不适用于所有的场合,所以ES7提出了"函数绑定"运算符,**暂时还是一个提案,但是Babel转码器已经支持) 函数绑定运算符是并排的双冒号(::),双冒号左边的是对象右边的是函数。该运算符会自动将左边的对象作为上下文环境(及this对象)绑定到右边的函数上

foo::bar //等同于 bar.bind(foo)
复制代码

(后期补充知识点)

尾调用优化

什么事尾调用

尾调用(Tail Call)是函数式变成的一个重要概念,本身非常简单,就是指某个函数的最后一步是调用另一个函数。

function f(){
	return g(x)
}
复制代码

尾调用之所以与其他调用不同,就在于其特殊的调用位置。

尾递归

函数调用自身称为递归。如果尾调用自身就称为尾递归。(递归非常耗费内存,因为需要同时保存成败上千个调用帧,很容易发生“栈溢出”错误(stackoverflow) 对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出”错误。

function factorial(n){
	if(n === 1) return 1
	return n*factorial(n-1)
}
factorial(5) //120
factorial(6) //720
复制代码

递归函数的改写

尾递归的实现往往需要改写递归函数,确保最后一步只调用自身。做到这一点的方法,就是把所有用到的内部变量改写成函数的参数。

严格模式

ES6的尾调用优化旨在严格模式下开启,正常模式下是无效的。

尾递归优化

尾递归只在严格模式下生效,那么在正常模式下,或者在那些不支持该功能的环境中我们需要:自己实现尾递归优化。 尾递归之所以需要优化,原因是调用栈太多造成溢出,只要减少调用栈就不会溢出。我们可以采用“循环”替换“递归”。

function sum(x,y){
	if(y>0){
		return sum(x +1,y-1)
	}else {
	retun x
	}
} // 这个数太大会溢出
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值