mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-29 05:42:20 +00:00
edit function
This commit is contained in:
parent
f389ef2692
commit
bb909143a9
@ -307,6 +307,12 @@ foo()
|
|||||||
|
|
||||||
从上面代码还可以看到,参数`mustBeProvided`的默认值等于`throwIfMissing`函数的运行结果(即函数名之后有一对圆括号),这表明参数的默认值不是在定义时执行,而是在运行时执行(即如果参数已经赋值,默认值中的函数就不会运行),这与python语言不一样。
|
从上面代码还可以看到,参数`mustBeProvided`的默认值等于`throwIfMissing`函数的运行结果(即函数名之后有一对圆括号),这表明参数的默认值不是在定义时执行,而是在运行时执行(即如果参数已经赋值,默认值中的函数就不会运行),这与python语言不一样。
|
||||||
|
|
||||||
|
另外,可以将参数默认值设为`undefined`,表明这个参数是可以省略的。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function foo(optional = undefined) { ··· }
|
||||||
|
```
|
||||||
|
|
||||||
## rest参数
|
## rest参数
|
||||||
|
|
||||||
ES6引入rest参数(形式为“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
|
ES6引入rest参数(形式为“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
|
||||||
|
@ -119,7 +119,7 @@ fproxy.foo; // 'Hello, foo'
|
|||||||
|
|
||||||
**(1)get(target, propKey, receiver)**
|
**(1)get(target, propKey, receiver)**
|
||||||
|
|
||||||
拦截对象属性的读取,比如`proxy.foo`和`proxy['foo']`,返回类型不限。最后一个参数receiver可选,当target对象设置了propKey属性的get函数时,receiver对象会绑定get函数的this对象。
|
拦截对象属性的读取,比如`proxy.foo`和`proxy['foo']`,返回类型不限。最后一个参数`receiver`可选,当`target`对象设置了`propKey`属性的`get`函数时,`receiver`对象会绑定`get`函数的`this`对象。
|
||||||
|
|
||||||
**(2)set(target, propKey, value, receiver)**
|
**(2)set(target, propKey, value, receiver)**
|
||||||
|
|
||||||
@ -177,15 +177,15 @@ fproxy.foo; // 'Hello, foo'
|
|||||||
|
|
||||||
**(15)construct(target, args, proxy)**
|
**(15)construct(target, args, proxy)**
|
||||||
|
|
||||||
拦截Proxy实例作为构造函数调用的操作,比如new proxy(...args)。
|
拦截Proxy实例作为构造函数调用的操作,比如`new proxy(...args)`。
|
||||||
|
|
||||||
## Proxy实例的方法
|
## Proxy实例的方法
|
||||||
|
|
||||||
下面是其中几个重要拦截方法的详细介绍。
|
下面是上面这些拦截方法的详细介绍。
|
||||||
|
|
||||||
### get()
|
### get()
|
||||||
|
|
||||||
get方法用于拦截某个属性的读取操作。上文已经有一个例子,下面是另一个拦截读取操作的例子。
|
`get`方法用于拦截某个属性的读取操作。上文已经有一个例子,下面是另一个拦截读取操作的例子。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var person = {
|
var person = {
|
||||||
@ -206,9 +206,50 @@ proxy.name // "张三"
|
|||||||
proxy.age // 抛出一个错误
|
proxy.age // 抛出一个错误
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码表示,如果访问目标对象不存在的属性,会抛出一个错误。如果没有这个拦截函数,访问不存在的属性,只会返回undefined。
|
上面代码表示,如果访问目标对象不存在的属性,会抛出一个错误。如果没有这个拦截函数,访问不存在的属性,只会返回`undefined`。
|
||||||
|
|
||||||
利用proxy,可以将读取属性的操作(get),转变为执行某个函数。
|
`get`方法可以继承。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
let proto = new Proxy({}, {
|
||||||
|
get(target, propertyKey, receiver) {
|
||||||
|
console.log('GET '+propertyKey);
|
||||||
|
return target[propertyKey];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let obj = Object.create(proto);
|
||||||
|
obj.xxx // "GET xxx"
|
||||||
|
```
|
||||||
|
|
||||||
|
上面代码中,拦截操作定义在Prototype对象上面,所以如果读取`obj`对象继承的属性时,拦截会生效。
|
||||||
|
|
||||||
|
下面的例子使用`get`拦截,实现数组读取负数的索引。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function createArray(...elements) {
|
||||||
|
let handler = {
|
||||||
|
get(target, propKey, receiver) {
|
||||||
|
let index = Number(propKey);
|
||||||
|
if (index < 0) {
|
||||||
|
propKey = String(target.length + index);
|
||||||
|
}
|
||||||
|
return Reflect.get(target, propKey, receiver);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let target = [];
|
||||||
|
target.push(...elements);
|
||||||
|
return new Proxy(target, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
let arr = createArray('a', 'b', 'c');
|
||||||
|
arr[-1] // c
|
||||||
|
```
|
||||||
|
|
||||||
|
上面代码中,数组的位置参数是`-1`,就会输出数组的倒数最后一个成员。
|
||||||
|
|
||||||
|
利用proxy,可以将读取属性的操作(`get`),转变为执行某个函数,从而实现属性的链式操作。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var pipe = (function () {
|
var pipe = (function () {
|
||||||
@ -229,11 +270,11 @@ var pipe = (function () {
|
|||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
|
|
||||||
var double = function (n) { return n*2 };
|
var double = n => n * 2;
|
||||||
var pow = function (n) { return n*n };
|
var pow = n => n * n;
|
||||||
var reverseInt = function (n) { return n.toString().split('').reverse().join('')|0 };
|
var reverseInt = n => n.toString().split('').reverse().join('') | 0;
|
||||||
|
|
||||||
pipe(3) . double . pow . reverseInt . get
|
pipe(3).double.pow.reverseInt.get
|
||||||
// 63
|
// 63
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -756,17 +797,27 @@ Proxy(target, {
|
|||||||
|
|
||||||
上面代码中,Proxy方法拦截target对象的属性赋值行为。它采用`Reflect.set`方法将值赋值给对象的属性,然后再部署额外的功能。
|
上面代码中,Proxy方法拦截target对象的属性赋值行为。它采用`Reflect.set`方法将值赋值给对象的属性,然后再部署额外的功能。
|
||||||
|
|
||||||
下面是get方法的例子。
|
下面是另一个例子。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var loggedObj = new Proxy(obj, {
|
var loggedObj = new Proxy(obj, {
|
||||||
get: function(target, name) {
|
get(target, name) {
|
||||||
console.log("get", target, name);
|
console.log('get', target, name);
|
||||||
return Reflect.get(target, name);
|
return Reflect.get(target, name);
|
||||||
|
},
|
||||||
|
deleteProperty(target, name) {
|
||||||
|
console.log('delete' + name);
|
||||||
|
return Reflect.deleteProperty(target, name);
|
||||||
|
},
|
||||||
|
has(target, name) {
|
||||||
|
console.log('has' + name);
|
||||||
|
return Reflect.has(target, name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
上面代码中,每一个Proxy对象的拦截操作(`get`、`delete`、`has`),内部都调用对应的Reflect方法,保证原生行为能够正常执行。添加的工作,就是将每一个操作输出一行日志。
|
||||||
|
|
||||||
## Reflect对象的方法
|
## Reflect对象的方法
|
||||||
|
|
||||||
Reflect对象的方法清单如下。
|
Reflect对象的方法清单如下。
|
||||||
|
@ -265,7 +265,7 @@ const nodes = Array.from(foo);
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
箭头函数取代Function.prototype.bind,不应再用self/\_this/that绑定 this。
|
箭头函数取代`Function.prototype.bind`,不应再用self/\_this/that绑定 this。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// bad
|
// bad
|
||||||
@ -281,6 +281,8 @@ const boundMethod = method.bind(this);
|
|||||||
const boundMethod = (...params) => method.apply(this, params);
|
const boundMethod = (...params) => method.apply(this, params);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
简单的、单行的、不会复用的函数,建议采用箭头函数。如果函数体较为复杂,行数较多,还是应该采用传统的函数写法。
|
||||||
|
|
||||||
所有配置项都应该集中在一个对象,放在最后一个参数,布尔值不可以直接作为参数。
|
所有配置项都应该集中在一个对象,放在最后一个参数,布尔值不可以直接作为参数。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -393,7 +395,7 @@ class PeekableQueue extends Queue {
|
|||||||
|
|
||||||
## 模块
|
## 模块
|
||||||
|
|
||||||
首先,Module语法是JavaScript模块的标准写法,坚持使用这种写法。使用import取代require。
|
首先,Module语法是JavaScript模块的标准写法,坚持使用这种写法。使用`import`取代`require`。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// bad
|
// bad
|
||||||
@ -405,7 +407,7 @@ const func2 = moduleA.func2;
|
|||||||
import { func1, func2 } from 'moduleA';
|
import { func1, func2 } from 'moduleA';
|
||||||
```
|
```
|
||||||
|
|
||||||
使用export取代module.exports。
|
使用`export`取代`module.exports`。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// commonJS的写法
|
// commonJS的写法
|
||||||
@ -431,6 +433,8 @@ const Breadcrumbs = React.createClass({
|
|||||||
export default Breadcrumbs
|
export default Breadcrumbs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
如果模块只有一个输出值,就使用`export default`,如果模块有多个输出值,就不使用`export default`,不要`export default`与普通的`export`同时使用。
|
||||||
|
|
||||||
不要在模块输入中使用通配符。因为这样可以确保你的模块之中,有一个默认输出(export default)。
|
不要在模块输入中使用通配符。因为这样可以确保你的模块之中,有一个默认输出(export default)。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
Loading…
x
Reference in New Issue
Block a user