mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-24 18:32:22 +00:00
add function's name property
This commit is contained in:
parent
1f9f4914bd
commit
24548c3f3f
@ -280,7 +280,7 @@ var args = [0, 1, 2];
|
|||||||
f(...args);
|
f(...args);
|
||||||
```
|
```
|
||||||
|
|
||||||
下面是扩展运算符取代apply方法的一个实际的例子,应用Math.max方法,简化求出一个数组最大元素的写法。
|
下面是扩展运算符取代`apply`方法的一个实际的例子,应用`Math.max`方法,简化求出一个数组最大元素的写法。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// ES5的写法
|
// ES5的写法
|
||||||
@ -295,7 +295,7 @@ Math.max(14, 3, 77);
|
|||||||
|
|
||||||
上面代码表示,由于JavaScript不提供求数组最大元素的函数,所以只能套用`Math.max`函数,将数组转为一个参数序列,然后求最大值。有了扩展运算符以后,就可以直接用`Math.max`了。
|
上面代码表示,由于JavaScript不提供求数组最大元素的函数,所以只能套用`Math.max`函数,将数组转为一个参数序列,然后求最大值。有了扩展运算符以后,就可以直接用`Math.max`了。
|
||||||
|
|
||||||
另一个例子是通过push函数,将一个数组添加到另一个数组的尾部。
|
另一个例子是通过`push`函数,将一个数组添加到另一个数组的尾部。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// ES5的写法
|
// ES5的写法
|
||||||
@ -309,7 +309,7 @@ var arr2 = [3, 4, 5];
|
|||||||
arr1.push(...arr2);
|
arr1.push(...arr2);
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码的ES5写法中,push方法的参数不能是数组,所以只好通过apply方法变通使用push方法。有了扩展运算符,就可以直接将数组传入push方法。
|
上面代码的ES5写法中,`push`方法的参数不能是数组,所以只好通过`apply`方法变通使用`push`方法。有了扩展运算符,就可以直接将数组传入`push`方法。
|
||||||
|
|
||||||
扩展运算符与正常的函数参数可以结合使用,非常灵活。
|
扩展运算符与正常的函数参数可以结合使用,非常灵活。
|
||||||
|
|
||||||
@ -426,7 +426,53 @@ var go = function*(){
|
|||||||
[...go()] // [1, 2, 3]
|
[...go()] // [1, 2, 3]
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码中,变量go是一个Generator函数,执行后返回的是一个遍历器,对这个遍历器执行扩展运算符,就会将内部遍历得到的值,转为一个数组。
|
上面代码中,变量go是一个Generator函数,执行后返回的是一个遍历器对象,对这个遍历器对象执行扩展运算符,就会将内部遍历得到的值,转为一个数组。
|
||||||
|
|
||||||
|
## name属性
|
||||||
|
|
||||||
|
函数的`name`属性,返回该函数的函数名。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function foo() {}
|
||||||
|
foo.name // "foo"
|
||||||
|
```
|
||||||
|
|
||||||
|
这个属性早就被浏览器广泛支持,但是直到ES6,才将其写入了标准。
|
||||||
|
|
||||||
|
需要注意的是,ES6对这个属性的行为做出了一些修改。如果将一个匿名函数赋值给一个变量,ES5的`name`属性,会返回空字符串,而ES6的`name`属性会返回实际的函数名。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var func1 = function () {};
|
||||||
|
|
||||||
|
// ES5
|
||||||
|
func1.name // ""
|
||||||
|
|
||||||
|
// ES6
|
||||||
|
func1.name // "func1"
|
||||||
|
```
|
||||||
|
|
||||||
|
上面代码中,变量`func1`等于一个匿名函数,ES5和ES6的`name`属性返回的值不一样。
|
||||||
|
|
||||||
|
如果将一个具名函数赋值给一个变量,则ES5和ES6的`name`属性都返回这个具名函数原本的名字。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const bar = function baz() {};
|
||||||
|
|
||||||
|
// ES5
|
||||||
|
bar.name // "baz"
|
||||||
|
|
||||||
|
// ES6
|
||||||
|
bar.name // "baz"
|
||||||
|
```
|
||||||
|
|
||||||
|
只有具名函数才有`name`这个属性,匿名函数是没有的。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
'name' in (function () {})
|
||||||
|
// false
|
||||||
|
'name' in (() => {})
|
||||||
|
// false
|
||||||
|
```
|
||||||
|
|
||||||
## 箭头函数
|
## 箭头函数
|
||||||
|
|
||||||
|
@ -77,11 +77,11 @@ export {
|
|||||||
|
|
||||||
上面代码使用as关键字,重命名了函数v1和v2的对外接口。重命名后,v2可以用不同的名字输出两次。
|
上面代码使用as关键字,重命名了函数v1和v2的对外接口。重命名后,v2可以用不同的名字输出两次。
|
||||||
|
|
||||||
最后,export命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,下面的import命令也是如此。
|
最后,`export`命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,下面的`import`命令也是如此。
|
||||||
|
|
||||||
## import命令
|
## import命令
|
||||||
|
|
||||||
使用export命令定义了模块的对外接口以后,其他JS文件就可以通过import命令加载这个模块(文件)。
|
使用`export`命令定义了模块的对外接口以后,其他JS文件就可以通过`import`命令加载这个模块(文件)。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// main.js
|
// main.js
|
||||||
@ -93,7 +93,7 @@ function setName(element) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码的import命令,就用于加载profile.js文件,并从中输入变量。import命令接受一个对象(用大括号表示),里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。
|
上面代码的`import`命令,就用于加载`profile.js`文件,并从中输入变量。`import`命令接受一个对象(用大括号表示),里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(`profile.js`)对外接口的名称相同。
|
||||||
|
|
||||||
如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。
|
如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ import { es6 } from './someModule';
|
|||||||
export default es6;
|
export default es6;
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码中,export和import语句可以结合在一起,写成一行。但是从可读性考虑,不建议采用这种写法,h应该采用标准写法。
|
上面代码中,`export`和`import`语句可以结合在一起,写成一行。但是从可读性考虑,不建议采用这种写法,而应该采用标准写法。
|
||||||
|
|
||||||
## 模块的整体输入
|
## 模块的整体输入
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ module命令后面跟一个变量,表示输入的模块定义在该变量上
|
|||||||
|
|
||||||
## export default命令
|
## export default命令
|
||||||
|
|
||||||
从前面的例子可以看出,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。
|
从前面的例子可以看出,使用`import`命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。
|
||||||
|
|
||||||
为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到`export default`命令,为模块指定默认输出。
|
为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到`export default`命令,为模块指定默认输出。
|
||||||
|
|
||||||
@ -203,9 +203,9 @@ import customName from './export-default';
|
|||||||
customName(); // 'foo'
|
customName(); // 'foo'
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码的import命令,可以用任意名称指向`export-default.js`输出的方法,这时就不需要知道原模块输出的函数名。需要注意的是,这时import命令后面,不使用大括号。
|
上面代码的import命令,可以用任意名称指向`export-default.js`输出的方法,这时就不需要知道原模块输出的函数名。需要注意的是,这时`import`命令后面,不使用大括号。
|
||||||
|
|
||||||
export default命令用在非匿名函数前,也是可以的。
|
`export default`命令用在非匿名函数前,也是可以的。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// export-default.js
|
// export-default.js
|
||||||
@ -222,7 +222,7 @@ function foo() {
|
|||||||
export default foo;
|
export default foo;
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码中,foo函数的函数名foo,在模块外部是无效的。加载的时候,视同匿名函数加载。
|
上面代码中,`foo`函数的函数名`foo`,在模块外部是无效的。加载的时候,视同匿名函数加载。
|
||||||
|
|
||||||
下面比较一下默认输出和正常输出。
|
下面比较一下默认输出和正常输出。
|
||||||
|
|
||||||
@ -236,20 +236,14 @@ import { crc32 } from 'crc32';
|
|||||||
export function crc32(){};
|
export function crc32(){};
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码的两组写法,第一组是使用`export default`时,对应的import语句不需要使用大括号;第二组是不使用`export default`时,对应的import语句需要使用大括号。
|
上面代码的两组写法,第一组是使用`export default`时,对应的`import`语句不需要使用大括号;第二组是不使用`export default`时,对应的`import`语句需要使用大括号。
|
||||||
|
|
||||||
`export default`命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此`export deault`命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能对应一个方法。
|
`export default`命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此`export deault`命令只能使用一次。所以,`import`命令后面才不用加大括号,因为只可能对应一个方法。
|
||||||
|
|
||||||
本质上,`export default`就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。所以,下面的写法是有效的。
|
本质上,`export default`就是输出一个叫做`default`的变量或方法,然后系统允许你为它取任意名字。所以,下面的写法是有效的。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// modules.js
|
// modules.js
|
||||||
export default function (x, y) {
|
|
||||||
return x * y;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 或者
|
|
||||||
|
|
||||||
function add(x, y) {
|
function add(x, y) {
|
||||||
return x * y;
|
return x * y;
|
||||||
};
|
};
|
||||||
|
@ -144,7 +144,7 @@ obj.hello() // hi
|
|||||||
|
|
||||||
## 方法的name属性
|
## 方法的name属性
|
||||||
|
|
||||||
函数的name属性,返回函数名。ES6为对象方法也添加了name属性。
|
函数的`name`属性,返回函数名。对象方法也是函数,因此也有`name`属性。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var person = {
|
var person = {
|
||||||
@ -160,9 +160,9 @@ person.sayName.name // "sayName"
|
|||||||
person.firstName.name // "get firstName"
|
person.firstName.name // "get firstName"
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码中,方法的name属性返回函数名(即方法名)。如果使用了取值函数,则会在方法名前加上get。如果是存值函数,方法名的前面会加上set。
|
上面代码中,方法的`name`属性返回函数名(即方法名)。如果使用了取值函数,则会在方法名前加上`get`。如果是存值函数,方法名的前面会加上`set`。
|
||||||
|
|
||||||
有两种特殊情况:bind方法创造的函数,name属性返回“bound”加上原函数的名字;Function构造函数创造的函数,name属性返回“anonymous”。
|
有两种特殊情况:`bind`方法创造的函数,`name`属性返回“bound”加上原函数的名字;`Function`构造函数创造的函数,`name`属性返回“anonymous”。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
(new Function()).name // "anonymous"
|
(new Function()).name // "anonymous"
|
||||||
@ -173,6 +173,21 @@ var doSomething = function() {
|
|||||||
doSomething.bind().name // "bound doSomething"
|
doSomething.bind().name // "bound doSomething"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
如果对象的方法是一个Symbol值,那么`name`属性返回的是这个Symbol值的描述。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const key1 = Symbol('description');
|
||||||
|
const key2 = Symbol();
|
||||||
|
let obj = {
|
||||||
|
[key1]() {},
|
||||||
|
[key2]() {},
|
||||||
|
};
|
||||||
|
obj[key1].name // "[description]"
|
||||||
|
obj[key2].name // ""
|
||||||
|
```
|
||||||
|
|
||||||
|
上面代码中,`key1`对应的Symbol值有描述,`key2`没有。
|
||||||
|
|
||||||
## Object.is()
|
## Object.is()
|
||||||
|
|
||||||
Object.is()用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
|
Object.is()用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
|
||||||
|
@ -62,6 +62,7 @@
|
|||||||
- Axel Rauschmayer, [Handling required parameters in ECMAScript 6](http://www.2ality.com/2014/04/required-parameters-es6.html)
|
- Axel Rauschmayer, [Handling required parameters in ECMAScript 6](http://www.2ality.com/2014/04/required-parameters-es6.html)
|
||||||
- Dmitry Soshnikov, [ES6 Notes: Default values of parameters](http://dmitrysoshnikov.com/ecmascript/es6-notes-default-values-of-parameters/): 介绍参数的默认值
|
- Dmitry Soshnikov, [ES6 Notes: Default values of parameters](http://dmitrysoshnikov.com/ecmascript/es6-notes-default-values-of-parameters/): 介绍参数的默认值
|
||||||
- Ragan Wald, [Destructuring and Recursion in ES6](http://raganwald.com/2015/02/02/destructuring.html): rest参数和扩展运算符的详细介绍
|
- Ragan Wald, [Destructuring and Recursion in ES6](http://raganwald.com/2015/02/02/destructuring.html): rest参数和扩展运算符的详细介绍
|
||||||
|
- Axel Rauschmayer, [The names of functions in ES6](http://www.2ality.com/2015/09/function-names-es6.html): 函数的name属性的详细介绍
|
||||||
|
|
||||||
## 对象
|
## 对象
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user