From 91d44bdb6fbfd0bfa381b9bdef6ae5d3aa086ea5 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 8 Jan 2016 19:17:16 +0800 Subject: [PATCH] edit set-map --- docs/fp.md | 12 ++++++++---- docs/function.md | 13 ++++++++++++- docs/set-map.md | 6 +++--- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/docs/fp.md b/docs/fp.md index b84d4cd..e9f1ac6 100644 --- a/docs/fp.md +++ b/docs/fp.md @@ -1,6 +1,6 @@ # 函数式编程 -从一诞生,JavaScript语言就具有函数式编程的烙印。它将函数作为一种独立的数据类型,与其他数据类型处于完全平等的地位。在JavaScript语言中,你可以采用面向对象编程,也可以采用函数式编程。有人甚至说,JavaScript是有史以来第一种被大规模采用的函数式编程语言。 +JavaScript语言从一诞生,就具有函数式编程的烙印。它将函数作为一种独立的数据类型,与其他数据类型处于完全平等的地位。在JavaScript语言中,你可以采用面向对象编程,也可以采用函数式编程。有人甚至说,JavaScript是有史以来第一种被大规模采用的函数式编程语言。 ES6的种种新增功能,使得函数式编程变得更方便、更强大。本章介绍ES6如何进行函数式编程。 @@ -37,7 +37,7 @@ f.comp = (...fs) => { ## 参数倒置 -参数倒置(flip)指的是改变函数参数的顺序。 +参数倒置(flip)指的是改变函数前两个参数的顺序。 ```javascript var divide = (a, b) => a / b; @@ -45,9 +45,13 @@ var flip = f.flip(divide); flip(10, 5) // 0.5 flip(1, 10) // 10 + +var three = (a, b, c) => [a, b, c]; +var flip = f.flip(three); +flip(1, 2, 3); // => [2, 1, 3] ``` -上面代码中,如果按照正常的参数顺序,10除以5等于2。但是,参数倒置以后得到的新函数,结果就是5除以10,结果得到0.5。 +上面代码中,如果按照正常的参数顺序,10除以5等于2。但是,参数倒置以后得到的新函数,结果就是5除以10,结果得到0.5。如果原函数有3个参数,则只颠倒前两个参数的位置。 参数倒置的代码非常简单。 @@ -55,7 +59,7 @@ flip(1, 10) // 10 let f = {}; f.flip = fn => - (...args) => fn.apply(null, args.reverse()); + (a, b, ...args) => fn(b, a, ...args.reverse()); ``` ## 执行边界 diff --git a/docs/function.md b/docs/function.md index 2b319ba..cd3cd71 100644 --- a/docs/function.md +++ b/docs/function.md @@ -1138,7 +1138,7 @@ function addOne(a){ } ``` -上面的函数不会进行尾调用优化,因为内层函数inner用到了,外层函数addOne的内部变量one。 +上面的函数不会进行尾调用优化,因为内层函数`inner`用到了,外层函数`addOne`的内部变量`one`。 ### 尾递归 @@ -1238,6 +1238,17 @@ factorial(5) // 120 总结一下,递归本质上是一种循环操作。纯粹的函数式编程语言没有循环操作命令,所有的循环都用递归实现,这就是为什么尾递归对这些语言极其重要。对于其他支持“尾调用优化”的语言(比如Lua,ES6),只需要知道循环可以用递归代替,而一旦使用递归,就最好使用尾递归。 +### 严格模式 + +ES6的尾调用优化只在严格模式下开启,正常模式是无效的。 + +这是因为在正常模式下,函数内部有两个变量,可以跟踪函数的调用栈。 + +- `arguments`:返回调用时函数的参数。 +- `func.caller`:返回调用当前函数的那个函数。 + +尾调用优化发生时,函数的调用栈会改写,因此上面两个变量就会失真。严格模式禁用这两个变量,所以尾调用模式仅在严格模式下生效。 + ## 函数参数的尾逗号 ES7有一个[提案](https://github.com/jeffmo/es-trailing-function-commas),允许函数的最后一个参数有尾逗号(trailing comma)。 diff --git a/docs/set-map.md b/docs/set-map.md index 43c2324..0169068 100644 --- a/docs/set-map.md +++ b/docs/set-map.md @@ -328,7 +328,7 @@ ws.delete(window); ws.has(window); // false ``` -WeakSet没有size属性,没有办法遍历它的成员。 +WeakSet没有`size`属性,没有办法遍历它的成员。 ```javascript ws.size // undefined @@ -338,11 +338,11 @@ ws.forEach(function(item){ console.log('WeakSet has ' + item)}) // TypeError: undefined is not a function ``` -上面代码试图获取size和forEach属性,结果都不能成功。 +上面代码试图获取`size`和`forEach`属性,结果都不能成功。 WeakSet不能遍历,是因为成员都是弱引用,随时可能消失,遍历机制无法保证成员的存在,很可能刚刚遍历结束,成员就取不到了。WeakSet的一个用处,是储存DOM节点,而不用担心这些节点从文档移除时,会引发内存泄漏。 -下面是WeakMap的另一个例子。 +下面是WeakSet的另一个例子。 ```javascript const foos = new WeakSet()