diff --git a/docs/function.md b/docs/function.md index 26ef1f5..e87ade1 100644 --- a/docs/function.md +++ b/docs/function.md @@ -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 +``` ## 箭头函数 diff --git a/docs/module.md b/docs/module.md index 6deacfb..fb46a36 100644 --- a/docs/module.md +++ b/docs/module.md @@ -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; }; diff --git a/docs/object.md b/docs/object.md index 487f8cd..6f0fe00 100644 --- a/docs/object.md +++ b/docs/object.md @@ -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等于自身。 diff --git a/docs/reference.md b/docs/reference.md index 1935b89..a9578d4 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -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属性的详细介绍 ## 对象