edit set-map

This commit is contained in:
ruanyf
2016-01-08 19:17:16 +08:00
parent 73be57cbeb
commit 91d44bdb6f
3 changed files with 23 additions and 8 deletions
+8 -4
View File
@@ -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());
```
## 执行边界
+12 -1
View File
@@ -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)。
+3 -3
View File
@@ -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
```
上面代码试图获取sizeforEach属性,结果都不能成功。
上面代码试图获取`size``forEach`属性,结果都不能成功。
WeakSet不能遍历,是因为成员都是弱引用,随时可能消失,遍历机制无法保证成员的存在,很可能刚刚遍历结束,成员就取不到了。WeakSet的一个用处,是储存DOM节点,而不用担心这些节点从文档移除时,会引发内存泄漏。
下面是WeakMap的另一个例子。
下面是WeakSet的另一个例子。
```javascript
const foos = new WeakSet()