From 70efc5d7d67067d611837431d53f93193f5971f9 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 11 Oct 2017 13:07:23 +0800 Subject: [PATCH] docs(set): edit set/forEach --- docs/class.md | 8 +++--- docs/function.md | 64 ------------------------------------------------ docs/set-map.md | 18 ++++++++------ 3 files changed, 14 insertions(+), 76 deletions(-) diff --git a/docs/class.md b/docs/class.md index 18cfdc2..e07142a 100644 --- a/docs/class.md +++ b/docs/class.md @@ -842,16 +842,16 @@ class Foo { 上面代码中,老写法的静态属性定义在类的外部。整个类生成以后,再生成静态属性。这样让人很容易忽略这个静态属性,也不符合相关代码应该放在一起的代码组织原则。另外,新写法是显式声明(declarative),而不是赋值处理,语义更好。 -## new.target属性 +## new.target 属性 -`new`是从构造函数生成实例的命令。ES6 为`new`命令引入了一个`new.target`属性,该属性一般用在构造函数之中,返回`new`命令作用于的那个构造函数。如果构造函数不是通过`new`命令调用的,`new.target`会返回`undefined`,因此这个属性可以用来确定构造函数是怎么调用的。 +`new`是从构造函数生成实例对象的命令。ES6 为`new`命令引入了一个`new.target`属性,该属性一般用在构造函数之中,返回`new`命令作用于的那个构造函数。如果构造函数不是通过`new`命令调用的,`new.target`会返回`undefined`,因此这个属性可以用来确定构造函数是怎么调用的。 ```javascript function Person(name) { if (new.target !== undefined) { this.name = name; } else { - throw new Error('必须使用new生成实例'); + throw new Error('必须使用 new 命令生成实例'); } } @@ -860,7 +860,7 @@ function Person(name) { if (new.target === Person) { this.name = name; } else { - throw new Error('必须使用 new 生成实例'); + throw new Error('必须使用 new 命令生成实例'); } } diff --git a/docs/function.md b/docs/function.md index 3472048..61188c6 100644 --- a/docs/function.md +++ b/docs/function.md @@ -586,70 +586,6 @@ foo.bind({}).name // "bound foo" (function(){}).bind({}).name // "bound " ``` -## new.target - -JavaScript 语言的函数可以直接调用,也可以通过`new`命令调用。 - -```javascript -function fn() { - this.foo = 'hello'; -} - -// 调用方式一 -fn() - -// 调用方式二 -new fn() -``` - -以前,一般在函数内部通过`instanceof`运算符判断,函数到底是哪一种方式调用。 - -```javascript -function fn() { - if (this instanceof fn) { // 通过 new 命令调用 - this.foo = 'hello'; - } else { - throw new Error('该函数只能通过 new 调用'); - } -} - -// 报错 -fn() - -// 不报错 -new fn() -``` - -这种方法的问题是,如果通过`call()`、`apply()`、`bind()`这些方法绑定`this`,就会判断失败。 - -```javascript -// 不报错 -fn.call(new fn()) -``` - -为了解决这个问题,精确判断是否通过`new`调用,ES6 引入了`new.target`属性。如果通过`new`调用,`new.target`将指向当前正在执行的函数,其他情况都指向`undefined`。 - -```javascript -function fn() { - if (new.target === fn) { // 通过 new 命令调用 - this.foo = 'hello'; - } else { - throw new Error('该函数只能通过 new 调用'); - } -} - -// 报错 -fn() - -// 报错 -fn.call(new fn()) - -// 不报错 -new fn() -``` - -注意,`new.target`只能在函数体内部使用,如果在函数体外部使用就会报错。 - ## 箭头函数 ### 基本用法 diff --git a/docs/set-map.md b/docs/set-map.md index 8025eea..2004b9a 100644 --- a/docs/set-map.md +++ b/docs/set-map.md @@ -55,7 +55,7 @@ set.size // 56 [...new Set(array)] ``` -向Set加入值的时候,不会发生类型转换,所以`5`和`"5"`是两个不同的值。Set内部判断两个值是否不同,使用的算法叫做“Same-value equality”,它类似于精确相等运算符(`===`),主要的区别是`NaN`等于自身,而精确相等运算符认为`NaN`不等于自身。 +向 Set 加入值的时候,不会发生类型转换,所以`5`和`"5"`是两个不同的值。Set 内部判断两个值是否不同,使用的算法叫做“Same-value equality”,它类似于精确相等运算符(`===`),主要的区别是`NaN`等于自身,而精确相等运算符认为`NaN`不等于自身。 ```javascript let set = new Set(); @@ -217,17 +217,19 @@ for (let x of set) { **(2)`forEach()`** -Set结构的实例的`forEach`方法,用于对每个成员执行某种操作,没有返回值。 +Set 结构的实例与数组一样,也拥有`forEach`方法,用于对每个成员执行某种操作,没有返回值。 ```javascript -let set = new Set([1, 2, 3]); -set.forEach((value, key) => console.log(value * 2) ) -// 2 -// 4 -// 6 +set = new Set([1, 4, 9]); +set.forEach((value, key) => console.log(key + ' : ' + value)) +// 1 : 1 +// 4 : 4 +// 9 : 9 ``` -上面代码说明,`forEach`方法的参数就是一个处理函数。该函数的参数依次为键值、键名、集合本身(上例省略了该参数)。另外,`forEach`方法还可以有第二个参数,表示绑定的`this`对象。 +上面代码说明,`forEach`方法的参数就是一个处理函数。该函数的参数与数组的`forEach`一致,依次为键值、键名、集合本身(上例省略了该参数)。这里需要注意,Set 结构的键名就是键值(两者是同一个值),因此第一个参数与第二个参数的值永远都是一样的。 + +另外,`forEach`方法还可以有第二个参数,表示绑定处理函数内部的`this`对象。 **(3)遍历的应用**