前端基础知识
2020-02-02 12:19 GarfieldEr007 阅读(153) 评论(0) 编辑 收藏 举报一、创建函数
函数声明
function fnName(){
}
函数表达式
var fnName = function(){
}
使用Function构造函数
// 参数:Function 接收任意多的参数,但最后一个参数总被认为是函数体,前面的参数是传入新函数的参数
var fnName = new Function(a, b, c, 'return a + b + c')
【ES6】箭头函数
var fnName = () => {
}
二、函数的内部属性
anguments
- 类型:类数组对象,包含着传入函数的所有参数,和length属性
- 属性:
- anguments.length // 实际传入函数参数的个数
- anguments.callee【严格模式报错】 // 指向拥有这个anguments对象的函数,即函数本身
this
函数据以执行的执行环境
箭头函数无 this
三、函数的属性和方法
属性
fnName.caller
- 描述:保存着调用当前函数的函数的引用,如果在全局作用域调用当前函数,则返回
null
fnName.length
- 描述:表示函数希望接收的命名参数的个数
注意:anguments.length 是实际传入函数参数的个数,而 fnName.length 是函数希望接收命名参数的个数,【ES6函数默认值对length的影响】:指定默认值以及在指定默认值的参数之后的所有参数,都不会计算到length中
fnName.prototype
- 描述:保存函数的原型对象
【ES6】fnName.name
- 描述:获取函数的函数名
- 返回值:
- 对于函数声明:返回函数名
- 对于匿名函数表达式:ES5返回空字符串,ES6返回变量的名字
- 对于具名函数表达式:返回函数的原名字
- 对于使用 new Function 创建的函数:返回 'anonymous'
- 对于使用bind方法返回的函数:返回 'bound 函数名'
方法
fnName.apply()
fnName.call()
- 描述:上面两个方法都用来在特殊的作用域调用函数,实际上等于设置函数体内的
this
对象的值 - 参数:
- 第一个参数都是 this 的值
- 第二个参数:
apply
接收anguments
对象或数组,call
必须逐个列举出来
fnName.bind()
- 描述:根据已有函数,创建一个被绑定新
this
值的函数 - 参数:指定
this
值 - 返回值:
{Function}
被指定this
值的新函数
四、ES6对函数的扩展
参数默认值
function (a = 2, b = 3){
}
【注意:函数的length属性,不会计算指定默认值的参数以及其后的所有参数】
rest参数 [...变量名]
- 描述:用于获取函数多余的参数,将其放入一个数组
- 注意:
- 1、rest参数后面,不能有其他参数,否则会报错
- 2、rest参数不会被计算到函数的length属性中
箭头函数
箭头函数有几点需要注意:
- 函数体内的
this
对象是函数定义是所在的对象,而不是使用时的对象 - 不能用箭头函数当做构造函数,也就是说不能使用new命令,否则会报错
- 不可以使用
arguments
对象,该对象在函数体内不存在。如果要用,可以用Rest参数
代替。 - 不可以使用
yield
命令,因此箭头函数不能用作Generator
函数。 - 由于箭头函数没有自己的
this
,所以当然也就不能用call()
、apply()
、bind()
这些方法去改变this
的指向。
尾递归
【注意:ES6的尾调用优化只在严格模式下开启,正常模式是无效的。】
ES6明确规定,所有ECMAScript的实现,都必须部署“尾调用优化”。这就是说,在ES6中,只要使用尾递归,就不会发生栈溢出,相对节省内存。
相关概念:
1、尾调用:函数的最后一步调用另一个函数,叫做尾调用
尾调用的好处是:只保留内层函数的调用帧,节省内存
2、尾递归:函数尾调用自身,叫做尾递归
3、柯里化:将多参数函数转成单参数函数
因为尾调用优化的本质是,只保留内层函数的调用帧,ES6的尾调用只在严格模式下生效,那么在非严格模式下是否可以进行尾调用优化呢?但是可以的,有两种方案,一种是使用蹦床函数,一种是真正的尾调用,阮一峰的教程里有讲
from: http://blog.poetries.top/js-knowledge-note/#/note/basis/func