Skip to content

Commit bb90914

Browse files
committed
edit function
1 parent f389ef2 commit bb90914

File tree

3 files changed

+77
-16
lines changed

3 files changed

+77
-16
lines changed

docs/function.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,12 @@ foo()
307307

308308
从上面代码还可以看到,参数`mustBeProvided`的默认值等于`throwIfMissing`函数的运行结果(即函数名之后有一对圆括号),这表明参数的默认值不是在定义时执行,而是在运行时执行(即如果参数已经赋值,默认值中的函数就不会运行),这与python语言不一样。
309309

310+
另外,可以将参数默认值设为`undefined`,表明这个参数是可以省略的。
311+
312+
```javascript
313+
function foo(optional = undefined) { ··· }
314+
```
315+
310316
## rest参数
311317

312318
ES6引入rest参数(形式为“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

docs/proxy.md

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ fproxy.foo; // 'Hello, foo'
119119

120120
**(1)get(target, propKey, receiver)**
121121

122-
拦截对象属性的读取,比如`proxy.foo``proxy['foo']`,返回类型不限。最后一个参数receiver可选,当target对象设置了propKey属性的get函数时,receiver对象会绑定get函数的this对象
122+
拦截对象属性的读取,比如`proxy.foo``proxy['foo']`,返回类型不限。最后一个参数`receiver`可选,当`target`对象设置了`propKey`属性的`get`函数时,`receiver`对象会绑定`get`函数的`this`对象
123123

124124
**(2)set(target, propKey, value, receiver)**
125125

@@ -177,15 +177,15 @@ fproxy.foo; // 'Hello, foo'
177177

178178
**(15)construct(target, args, proxy)**
179179

180-
拦截Proxy实例作为构造函数调用的操作,比如new proxy(...args)。
180+
拦截Proxy实例作为构造函数调用的操作,比如`new proxy(...args)`
181181

182182
## Proxy实例的方法
183183

184-
下面是其中几个重要拦截方法的详细介绍
184+
下面是上面这些拦截方法的详细介绍
185185

186186
### get()
187187

188-
get方法用于拦截某个属性的读取操作。上文已经有一个例子,下面是另一个拦截读取操作的例子。
188+
`get`方法用于拦截某个属性的读取操作。上文已经有一个例子,下面是另一个拦截读取操作的例子。
189189

190190
```javascript
191191
var person = {
@@ -206,9 +206,50 @@ proxy.name // "张三"
206206
proxy.age // 抛出一个错误
207207
```
208208

209-
上面代码表示,如果访问目标对象不存在的属性,会抛出一个错误。如果没有这个拦截函数,访问不存在的属性,只会返回undefined
209+
上面代码表示,如果访问目标对象不存在的属性,会抛出一个错误。如果没有这个拦截函数,访问不存在的属性,只会返回`undefined`
210210

211-
利用proxy,可以将读取属性的操作(get),转变为执行某个函数。
211+
`get`方法可以继承。
212+
213+
```javascript
214+
let proto = new Proxy({}, {
215+
get(target, propertyKey, receiver) {
216+
console.log('GET '+propertyKey);
217+
return target[propertyKey];
218+
}
219+
});
220+
221+
let obj = Object.create(proto);
222+
obj.xxx // "GET xxx"
223+
```
224+
225+
上面代码中,拦截操作定义在Prototype对象上面,所以如果读取`obj`对象继承的属性时,拦截会生效。
226+
227+
下面的例子使用`get`拦截,实现数组读取负数的索引。
228+
229+
```javascript
230+
function createArray(...elements) {
231+
let handler = {
232+
get(target, propKey, receiver) {
233+
let index = Number(propKey);
234+
if (index < 0) {
235+
propKey = String(target.length + index);
236+
}
237+
return Reflect.get(target, propKey, receiver);
238+
}
239+
};
240+
241+
let target = [];
242+
target.push(...elements);
243+
return new Proxy(target, handler);
244+
}
245+
246+
let arr = createArray('a', 'b', 'c');
247+
arr[-1] // c
248+
```
249+
250+
上面代码中,数组的位置参数是`-1`,就会输出数组的倒数最后一个成员。
251+
252+
利用proxy,可以将读取属性的操作(`get`),转变为执行某个函数,从而实现属性的链式操作。
212253

213254
```javascript
214255
var pipe = (function () {
@@ -229,11 +270,11 @@ var pipe = (function () {
229270
}
230271
}());
231272

232-
var double = function (n) { return n*2 };
233-
var pow = function (n) { return n*n };
234-
var reverseInt = function (n) { return n.toString().split('').reverse().join('')|0 };
273+
var double = n => n * 2;
274+
var pow = n => n * n;
275+
var reverseInt = n => n.toString().split('').reverse().join('') | 0;
235276

236-
pipe(3) . double . pow . reverseInt . get
277+
pipe(3).double.pow.reverseInt.get
237278
// 63
238279
```
239280

@@ -756,17 +797,27 @@ Proxy(target, {
756797

757798
上面代码中,Proxy方法拦截target对象的属性赋值行为。它采用`Reflect.set`方法将值赋值给对象的属性,然后再部署额外的功能。
758799

759-
下面是get方法的例子
800+
下面是另一个例子
760801

761802
```javascript
762803
var loggedObj = new Proxy(obj, {
763-
get: function(target, name) {
764-
console.log("get", target, name);
804+
get(target, name) {
805+
console.log('get', target, name);
765806
return Reflect.get(target, name);
807+
},
808+
deleteProperty(target, name) {
809+
console.log('delete' + name);
810+
return Reflect.deleteProperty(target, name);
811+
},
812+
has(target, name) {
813+
console.log('has' + name);
814+
return Reflect.has(target, name);
766815
}
767816
});
768817
```
769818

819+
上面代码中,每一个Proxy对象的拦截操作(`get``delete``has`),内部都调用对应的Reflect方法,保证原生行为能够正常执行。添加的工作,就是将每一个操作输出一行日志。
820+
770821
## Reflect对象的方法
771822

772823
Reflect对象的方法清单如下。

docs/style.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ const nodes = Array.from(foo);
265265
});
266266
```
267267

268-
箭头函数取代Function.prototype.bind,不应再用self/\_this/that绑定 this。
268+
箭头函数取代`Function.prototype.bind`,不应再用self/\_this/that绑定 this。
269269

270270
```javascript
271271
// bad
@@ -281,6 +281,8 @@ const boundMethod = method.bind(this);
281281
const boundMethod = (...params) => method.apply(this, params);
282282
```
283283

284+
简单的、单行的、不会复用的函数,建议采用箭头函数。如果函数体较为复杂,行数较多,还是应该采用传统的函数写法。
285+
284286
所有配置项都应该集中在一个对象,放在最后一个参数,布尔值不可以直接作为参数。
285287

286288
```bash
@@ -393,7 +395,7 @@ class PeekableQueue extends Queue {
393395
394396
## 模块
395397
396-
首先,Module语法是JavaScript模块的标准写法,坚持使用这种写法。使用import取代require
398+
首先,Module语法是JavaScript模块的标准写法,坚持使用这种写法。使用`import`取代`require`
397399
398400
```javascript
399401
// bad
@@ -405,7 +407,7 @@ const func2 = moduleA.func2;
405407
import { func1, func2 } from 'moduleA';
406408
```
407409
408-
使用export取代module.exports。
410+
使用`export`取代`module.exports`
409411
410412
```javascript
411413
// commonJS的写法
@@ -431,6 +433,8 @@ const Breadcrumbs = React.createClass({
431433
export default Breadcrumbs
432434
```
433435
436+
如果模块只有一个输出值,就使用`export default`,如果模块有多个输出值,就不使用`export default`,不要`export default`与普通的`export`同时使用。
437+
434438
不要在模块输入中使用通配符。因为这样可以确保你的模块之中,有一个默认输出(export default)。
435439
436440
```javascript

0 commit comments

Comments
 (0)