1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 10:22:23 +00:00

add function's name property

This commit is contained in:
ruanyf 2015-09-13 21:17:33 +08:00
parent 1f9f4914bd
commit 24548c3f3f
4 changed files with 80 additions and 24 deletions

View File

@ -280,7 +280,7 @@ var args = [0, 1, 2];
f(...args);
```
下面是扩展运算符取代apply方法的一个实际的例子应用Math.max方法简化求出一个数组最大元素的写法。
下面是扩展运算符取代`apply`方法的一个实际的例子,应用`Math.max`方法,简化求出一个数组最大元素的写法。
```javascript
// ES5的写法
@ -295,7 +295,7 @@ Math.max(14, 3, 77);
上面代码表示由于JavaScript不提供求数组最大元素的函数所以只能套用`Math.max`函数,将数组转为一个参数序列,然后求最大值。有了扩展运算符以后,就可以直接用`Math.max`了。
另一个例子是通过push函数将一个数组添加到另一个数组的尾部。
另一个例子是通过`push`函数,将一个数组添加到另一个数组的尾部。
```javascript
// ES5的写法
@ -309,7 +309,7 @@ var arr2 = [3, 4, 5];
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是一个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
```
## 箭头函数

View File

@ -77,11 +77,11 @@ export {
上面代码使用as关键字重命名了函数v1和v2的对外接口。重命名后v2可以用不同的名字输出两次。
最后export命令可以出现在模块的任何位置只要处于模块顶层就可以。如果处于块级作用域内就会报错下面的import命令也是如此。
最后,`export`命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,下面的`import`命令也是如此。
## import命令
使用export命令定义了模块的对外接口以后其他JS文件就可以通过import命令加载这个模块文件
使用`export`命令定义了模块的对外接口以后其他JS文件就可以通过`import`命令加载这个模块(文件)。
```javascript
// main.js
@ -93,7 +93,7 @@ function setName(element) {
}
```
上面代码的import命令就用于加载profile.js文件并从中输入变量。import命令接受一个对象用大括号表示里面指定要从其他模块导入的变量名。大括号里面的变量名必须与被导入模块profile.js对外接口的名称相同。
上面代码的`import`命令,就用于加载`profile.js`文件,并从中输入变量。`import`命令接受一个对象(用大括号表示),里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(`profile.js`)对外接口的名称相同。
如果想为输入的变量重新取一个名字import命令要使用as关键字将输入的变量重命名。
@ -127,7 +127,7 @@ import { es6 } from './someModule';
export default es6;
```
上面代码中export和import语句可以结合在一起写成一行。但是从可读性考虑不建议采用这种写法h应该采用标准写法。
上面代码中,`export``import`语句可以结合在一起,写成一行。但是从可读性考虑,不建议采用这种写法,应该采用标准写法。
## 模块的整体输入
@ -182,7 +182,7 @@ module命令后面跟一个变量表示输入的模块定义在该变量上
## export default命令
从前面的例子可以看出使用import命令的时候用户需要知道所要加载的变量名或函数名否则无法加载。但是用户肯定希望快速上手未必愿意阅读文档去了解模块有哪些属性和方法。
从前面的例子可以看出,使用`import`命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。
为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到`export default`命令,为模块指定默认输出。
@ -203,9 +203,9 @@ import customName from './export-default';
customName(); // 'foo'
```
上面代码的import命令可以用任意名称指向`export-default.js`输出的方法这时就不需要知道原模块输出的函数名。需要注意的是这时import命令后面不使用大括号。
上面代码的import命令可以用任意名称指向`export-default.js`输出的方法,这时就不需要知道原模块输出的函数名。需要注意的是,这时`import`命令后面,不使用大括号。
export default命令用在非匿名函数前也是可以的。
`export default`命令用在非匿名函数前,也是可以的。
```javascript
// export-default.js
@ -222,7 +222,7 @@ function foo() {
export default foo;
```
上面代码中foo函数的函数名foo在模块外部是无效的。加载的时候视同匿名函数加载。
上面代码中,`foo`函数的函数名`foo`,在模块外部是无效的。加载的时候,视同匿名函数加载。
下面比较一下默认输出和正常输出。
@ -236,20 +236,14 @@ import { crc32 } from '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
// modules.js
export default function (x, y) {
return x * y;
};
// 或者
function add(x, y) {
return x * y;
};

View File

@ -144,7 +144,7 @@ obj.hello() // hi
## 方法的name属性
函数的name属性返回函数名。ES6为对象方法也添加了name属性。
函数的`name`属性,返回函数名。对象方法也是函数,因此也有`name`属性。
```javascript
var person = {
@ -160,9 +160,9 @@ person.sayName.name // "sayName"
person.firstName.name // "get firstName"
```
上面代码中方法的name属性返回函数名即方法名。如果使用了取值函数则会在方法名前加上get。如果是存值函数方法名的前面会加上set。
上面代码中,方法的`name`属性返回函数名(即方法名)。如果使用了取值函数,则会在方法名前加上`get`。如果是存值函数,方法名的前面会加上`set`
有两种特殊情况bind方法创造的函数name属性返回“bound”加上原函数的名字Function构造函数创造的函数name属性返回“anonymous”。
有两种特殊情况:`bind`方法创造的函数,`name`属性返回“bound”加上原函数的名字`Function`构造函数创造的函数,`name`属性返回“anonymous”。
```javascript
(new Function()).name // "anonymous"
@ -173,6 +173,21 @@ var doSomething = function() {
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()用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0二是NaN等于自身。

View File

@ -62,6 +62,7 @@
- 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/): 介绍参数的默认值
- 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属性的详细介绍
## 对象