JavaScript 函数高级
函数对象的属性
属性name:函数名
属性length:返回函数参数个数
属性arguments:一个对应于 传递给函数的参数 的 类数组(array-like)对象
array-like 意味着它不是一个数组类型,而是一个对象类型:
- 但是它却拥有数组的一些特性,比如说 length,比如可以通过 index 索引来访问;
- 但是它却没有数组的一些方法,比如 filter、map 等;
注意
箭头函数没有arguments
函数的剩余参数
ES6 中引用了 rest parameter,可以将不定数量的参数放入到一个数组中:
如果最后一个参数是 ... 为前缀的,那么它会将剩余的参数放到该参数中,并且作为一个数组;
js
function foo(m, n, ...args) {}那么剩余参数和arguments有什么区别呢?
- 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参;
- arguments 对象
不是一个真正的数组,而 rest 参数是一个真正的数组,可以进行数组的所有操作; - arguments 是早期的
ECMAScript中为了方便去获取所有的参数提供的一个数据结构,而 rest 参数是 ES6 中提供并且希望以此来替代 arguments 的;
纯函数
函数式编程中有一个非常重要的概念叫纯函数,JavaScript 符合函数式编程的范式,所以也有纯函数的概念;
- 在
react开发中纯函数是被多次提及的; - 比如 react 中组件就被要求像是一个纯函数(为什么是像,因为还有 class 组件),redux 中有一个 reducer 的概念,也是要求必须是一个纯函数;
- 所以掌握纯函数对于理解很多框架的设计是非常有帮助的;
纯函数的维基百科定义
- 在程序设计中,若一个函数符合以下条件,那么这个函数被称为纯函数:
- 此函数
在相同的输入值时,需产生相同的输出。 - 函数的
输出和输入值以外的其他隐藏信息或状态无关,也和由 I/O 设备产生的外部输出无关。 - 该函数
不能有语义上可观察的函数副作用,诸如“触发事件”,使输出设备输出,或更改输出值以外物件的内容等。
简单总结:
确定的输入,一定会产生确定的输出;函数在执行过程中,不能产生副作用;
柯里化
柯里化(Currying)是把接收多个参数的函数,变成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数,而且返回结果的新函数的技术;
柯里化是一种函数的转换,将一个函数从可调用的 f(a, b, c) 转换为可调用的 f(a)(b)(c)
柯里化的优势
函数职责单一
- 在函数式编程中,我们其实往往希望一个函数处理的问题尽可能的单一,而不是将一大堆的处理过程交给一个函数来处理;
- 那么我们是否就可以将每次传入的参数在单一的函数中进行处理,处理完后在下一个函数中再使用处理后的结果;
函数参数复用
通过闭包,复用上层函数的参数
js
const makeAdder = (num) => (count) => num + count自动柯里化函数:将普通函数,转换成柯里化函数
js
function autoCurring(fn) {
function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args)
} else {
return function (...args2) {
return curried.apply(this, args.concat(args2))
}
}
}
return curried
}严格模式
JavaScript 历史的局限性:
- 长久以来,JavaScript 不断向前发展且并未带来任何兼容性问题;
- 新的特性被加入,旧的功能也没有改变,这么做有利于兼容旧代码;
- 但缺点是 JavaScript 创造者的
任何错误或不完善的决定也将永远被保留在 JavaScript 语言中;
在 ECMAScript5 标准中,JavaScript 提出了严格模式的概念(Strict Mode):
- 严格模式很好理解,是一种具有限制性的 JavaScript 模式,从而使代码隐式的脱离了 ”懒散(
sloppy)模式“; - 支持严格模式的浏览器在检测到代码中有严格模式时,会以
更加严格的方式对代码进行检测和执行;
严格模式对正常的 JavaScript 语义进行了一些限制:
- 严格模式通过
抛出错误来消除一些原有的 静默(silent)错误; - 严格模式让 JS 引擎在执行代码时可以进行更多的
优化(不需要对一些特殊的语法进行处理); - 严格模式禁用了在 ECMAScript 未来版本中可能会定义的一些语法;
如何开启严格模式?
- 在 js 文件首行填入
js
// "use strict"- 在某个函数中开启
js
function foo() {
'use strict'
}严格模式限制
- 无法
意外的创建全局变量 - 严格模式会使引起静默失败(
silently fail,注:不报错也没有任何效果)的赋值操作抛出异常 - 严格模式下试图删除不可删除的属性
- 严格模式不允许函数参数有
相同的名称 - 不允许 0 的
八进制语法 - 在严格模式下,不允许使用 with
- 在严格模式下,eval 不再为上层引用变量
- 严格模式下,this 绑定不会默认转成对象

