代码改变世界

前端基础知识

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