JavaScript 函数
函数的多变来源于参数的灵活多变和返回值的多变。如果参数是一般的数据类型或一般对象,这样的函数就是普通函数;如果函数的参数是函数,这就是我们所要知道的高级函数;如果创建的函数调用另外一部分(变量和参数已经预置),这样的函数就是偏函数。
此外,还有一点就是可选参数(optional parameter)的使用。
一、函数分类
普通函数
有函数名,参数,返回值,同名覆盖。示例代码如下:
1 | function add(a, b) { |
匿名函数
没有函数名,可以把函数赋值给变量和函数,或者作为回调函数使用。非常特殊的就是立即执行函数和闭包。立即执行函数示例代码如下:
1 | (function(){ |
闭包示例代码如下:
1 | var func = (function() { |
高级函数
高级函数就是可以把函数作为参数和返回值的函数。如上面的闭包。ECMAScript 中也提供大量的高级函数如 forEach
, every
, some
, reduce
等等。
偏函数
1 | function isType(type) { |
箭头函数
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的 this,arguments,super 或 new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。但它的特点就是更短,和解决匿名函数中 this 指向全局作用域的问题
本身不创建 this
- 箭头函数中的 this 是在箭头函数定义时就决定的,而且不可修改 (call, apply, bind)
- 箭头函数的 this 指向定义的时候,外层第一个普通函数的 this(或者说,其声明时所在的上下文的 this)
1 | let obj = { |
无法作为构造函数
当对构造函数 new 一个实例时,发生了如下步骤:
- 创建了一个空对象({})
- 为创建的空对象添加属性
__proto__
,并指向构造函数的原型 - 将创建的对象作为构造函数的上下文(改变 this 指向)
- 如果该函数没有返回对象,则返回 this
因为箭头函数并没有 prototype(即没有原型),没法让它的实例的__proto__
属性指向构造函数的 prototype,所以箭头函数不能作为构造函数,否则用 new 调用时会报错!
没有 arguments
箭头函数没有自己的 arguments 对象,在箭头函数中访问 arguments 实际上获得的是上一层函数执行环境中的值。
1 | let fn = (arr) => { |
因为传入箭头函数的参数数量不一,为了像 arguments 一样能获取全部参数,这里需要借助扩展运算符:
1 | let fn = (...arg) => { |
想了解更多箭头函数可以看MDN
二、函数参数
传入明确的参数
1 | function add(a, b) { |
使用 arguments 对象
1 | function add() { |
省略参数,参数默认值
1 | function sub(a, b) { |
对象参数
1 | var option = { |
ES6 中的函数参数
在 ES6 中,参数默认值,省略参数操作使用比较简便。示例代码如下:
1 | var area = (width=1, height=1) => width*height |
在 ES6 中,使用可选参数。示例代码如下:
1 | var add = (...nums) => { |
解构参数
1 | myFunc = function({x = 5,y = 8,z = 13} = {x:1,y:2,z:3}) { |
三、函数返回值
- 函数的返回值为基本数据类型,如字符串,数字,Boolean,null,undefined。示例代码如下:
1 | function add(a, b) { |
- 函数的返回值为对象。示例代码如下:
1 | function Robot(name) { |
不管是写原生还是 jQuery 插件,亦或其他插件,这种情况都不少见。更深入的了解可以参考 jQuery 源码。
- 返回值为函数
这个我们最为熟悉的莫过于闭包。具体可参考 老生常谈之闭包