From e01cc281d72c9f5d48e66a6b44551fd87a79070d Mon Sep 17 00:00:00 2001 From: azu Date: Tue, 19 Jul 2016 00:03:35 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat(loop):=20for...in=E6=96=87=E3=81=AB?= =?UTF-8?q?=E3=81=A4=E3=81=84=E3=81=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- prh.yml | 5 +++ source/basic/loop/README.md | 76 +++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/prh.yml b/prh.yml index 313b638341..ab0c7d5f27 100644 --- a/prh.yml +++ b/prh.yml @@ -111,6 +111,11 @@ rules: - expected: シングルスレッド patterns: - 単一スレッド + - expected: for...in + patterns: + - /for\.{1,2}in/ + - for-in + - for/in # typo - expected: $1進数 patterns: diff --git a/source/basic/loop/README.md b/source/basic/loop/README.md index 5b72a235a0..273188425a 100644 --- a/source/basic/loop/README.md +++ b/source/basic/loop/README.md @@ -4,10 +4,9 @@ author: azu # ループと反復処理 - プログラミングにおいて、同じ処理を繰り返すために同じコードを必要はありません。 ループや再帰呼び出し、イテレータなどを使い、反復処理は抽象化します。 -ここでは、もっとも基本的な反復処理となるループについてを学んでいきます。 +ここでは、もっとも基本的な反復処理と反復処理から抜ける制御文について学んでいきます。 ## while文 @@ -137,7 +136,7 @@ array.forEach(コールバック関数); ``` `forEach`メソッドのコールバック関数には、配列の先頭から順番に要素が渡されて実行されます。 -つまり、コールバック関数の`currentValue`には1, 2, 3 …という値が順番に渡されて実行されます。 +つまり、コールバック関数の`currentValue`には1, 2, 3, 4, 5という値が順番に渡されて実行されます。 ```js [1, 2, 3, 4, 5].forEach(currentValue => { @@ -256,6 +255,77 @@ var filterdArray = array.filter((currentValue, index, array) => { [import, filter-even-example.js](./src/continue/filter-even-example.js) +## for...in文 + +for...in文はオブジェクトのプロパティに対して、順不同で反復処理を行います。 + +```js +for (variable in object) + 実行する文; +``` + +次のコードでは`object`のプロパティ名を`key`変数に代入し反復処理をしています。 +`object`には、"a"、"b"、"c"の3つのプロパティ名があるため3回繰り返されます。 + +```js +var object = { + "a": 1,つかつ + "b": 2, + "c": 3 +}; +for (var key in object) { + var value = object[key]; + console.log(`key:${key}, value:${value}`); +} +// key:a, value:1 +// key:b, value:2 +// key:c, value:3 +``` + +オブジェクトに対する反復処理を行うのにfor...in文は有用に見えますが、 +多くの問題を持っているため、使うことを避けたほうがよいでしょう。 + +for...in文は配列オブジェクトに対しても利用できます。 +しかし、次のようなコードは期待した結果にはなりません。 +配列の要素が列挙されそうですが、実際には配列の添字が列挙されます。 +つまり、0、1という値が`num`に代入されるため、最終的に`total`が`1`となります。 + +```js +var numbers = [5, 10]; +var total = 0; +for (var num in numbers) { + total += num; +} +console.log(total); // => 1 +``` + +配列の内容に対して反復処理を行う場合は、for文や`forEach`メソッド、後述するfor...of文を使うべきでしょう。 + +また、オブジェクトに対してもfor...in文はプロトタイプチェーンにより意図しない挙動を起こすことがあります。 +プロトタイプチェーンについては第n章で詳しく解説します。 + +オブジェクトに対して列挙を行うには、`Object.keys()`、`Object.values()`、`Object.entries()`などのメソッドを利用します。 +先ほどのオブジェクトのキーと値を列挙するには次のように書くことができます。 +`Object.keys()`は`object`のプロパティ名の配列を返します。 + +```js +var object = { + "a": 1,つかつ + "b": 2, + "c": 3 +}; +Object.keys(object).forEach(key => { + const value = object[key]; + console.log(`key:${key}, value:${value}`); +}); +// key:a, value:1 +// key:b, value:2 +// key:c, value:3 +``` + +for...in文は正しく扱うのが難しいですが、代わりとなる手段が豊富にあります。 +そのため、for...in文を使うことよりも他の方法を考えた方がよいでしょう。 + ## [コラム] `let`ではなく`const`で反復処理をする 先ほどのfor文や`forEach`メソッドでは`let`を`const`に変更することはできませでした。 From 42f51ebdc6d112cd6973b9db612caa719ca17d84 Mon Sep 17 00:00:00 2001 From: azu Date: Tue, 19 Jul 2016 00:04:59 +0900 Subject: [PATCH 2/9] chore(loop): add TODO comment --- source/basic/loop/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/basic/loop/README.md b/source/basic/loop/README.md index 273188425a..8a5cc8ff8d 100644 --- a/source/basic/loop/README.md +++ b/source/basic/loop/README.md @@ -304,6 +304,8 @@ console.log(total); // => 1 また、オブジェクトに対してもfor...in文はプロトタイプチェーンにより意図しない挙動を起こすことがあります。 プロトタイプチェーンについては第n章で詳しく解説します。 + + オブジェクトに対して列挙を行うには、`Object.keys()`、`Object.values()`、`Object.entries()`などのメソッドを利用します。 先ほどのオブジェクトのキーと値を列挙するには次のように書くことができます。 `Object.keys()`は`object`のプロパティ名の配列を返します。 From 024dbdfc3be2617cca63a7542fac78a7ec5312d5 Mon Sep 17 00:00:00 2001 From: azu Date: Tue, 19 Jul 2016 00:07:39 +0900 Subject: [PATCH 3/9] =?UTF-8?q?refactor(loop):=20=E6=96=87=E3=82=92?= =?UTF-8?q?=E7=B4=B0=E3=81=8B=E3=81=8F=E5=8C=BA=E5=88=87=E3=81=A3=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/basic/loop/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/basic/loop/README.md b/source/basic/loop/README.md index 8a5cc8ff8d..9b1609e173 100644 --- a/source/basic/loop/README.md +++ b/source/basic/loop/README.md @@ -288,7 +288,8 @@ for (var key in object) { for...in文は配列オブジェクトに対しても利用できます。 しかし、次のようなコードは期待した結果にはなりません。 配列の要素が列挙されそうですが、実際には配列の添字が列挙されます。 -つまり、0、1という値が`num`に代入されるため、最終的に`total`が`1`となります。 +つまり、配列の添字は0から始まるため、0、1という値が`num`に代入されます。 +そのため、最終的に`total`が`1`となります。 ```js var numbers = [5, 10]; From 911bd839201d395f24226d281446634e7d80dc18 Mon Sep 17 00:00:00 2001 From: azu Date: Tue, 19 Jul 2016 00:15:29 +0900 Subject: [PATCH 4/9] =?UTF-8?q?style(loop):=20textlint=E3=81=AE=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/basic/loop/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/basic/loop/README.md b/source/basic/loop/README.md index 9b1609e173..208cc391d3 100644 --- a/source/basic/loop/README.md +++ b/source/basic/loop/README.md @@ -136,7 +136,7 @@ array.forEach(コールバック関数); ``` `forEach`メソッドのコールバック関数には、配列の先頭から順番に要素が渡されて実行されます。 -つまり、コールバック関数の`currentValue`には1, 2, 3, 4, 5という値が順番に渡されて実行されます。 +つまり、コールバック関数の`currentValue`には1から5の値が順番に渡されて実行されます。 ```js [1, 2, 3, 4, 5].forEach(currentValue => { @@ -265,11 +265,11 @@ for (variable in object) ``` 次のコードでは`object`のプロパティ名を`key`変数に代入し反復処理をしています。 -`object`には、"a"、"b"、"c"の3つのプロパティ名があるため3回繰り返されます。 +`object`には、3つのプロパティ名があるため3回繰り返されます。 ```js var object = { - "a": 1,つかつ + "a": 1, "b": 2, "c": 3 }; @@ -313,7 +313,7 @@ console.log(total); // => 1 ```js var object = { - "a": 1,つかつ + "a": 1, "b": 2, "c": 3 }; From f3af1cb8f775112af4e2a3f8d9b202466ebfe614 Mon Sep 17 00:00:00 2001 From: azu Date: Tue, 19 Jul 2016 21:19:22 +0900 Subject: [PATCH 5/9] =?UTF-8?q?refactor(loop):=20for...of=20+=20=E9=85=8D?= =?UTF-8?q?=E5=88=97=E3=81=AE=E5=86=97=E9=95=B7=E3=81=AA=E8=A1=A8=E7=8F=BE?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/basic/loop/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/source/basic/loop/README.md b/source/basic/loop/README.md index 208cc391d3..2e377b27a0 100644 --- a/source/basic/loop/README.md +++ b/source/basic/loop/README.md @@ -285,11 +285,9 @@ for (var key in object) { オブジェクトに対する反復処理を行うのにfor...in文は有用に見えますが、 多くの問題を持っているため、使うことを避けたほうがよいでしょう。 -for...in文は配列オブジェクトに対しても利用できます。 -しかし、次のようなコードは期待した結果にはなりません。 -配列の要素が列挙されそうですが、実際には配列の添字が列挙されます。 -つまり、配列の添字は0から始まるため、0、1という値が`num`に代入されます。 -そのため、最終的に`total`が`1`となります。 +for...in文は配列オブジェクトに対しても利用できますが、期待した結果にはなりません。 +次のコードでは、配列の要素が列挙されそうですが、実際には配列の添字が列挙されます。 +つまり、配列の添字は0から始まるため、0、1という値が順番に`num`へと代入されます。 ```js var numbers = [5, 10]; From cde49fa861e7abd4ccee13b8d8dd231c87a4fd22 Mon Sep 17 00:00:00 2001 From: azu Date: Tue, 19 Jul 2016 21:20:38 +0900 Subject: [PATCH 6/9] =?UTF-8?q?refactor(loop):=20=E6=94=B9=E8=A1=8C?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/basic/loop/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/basic/loop/README.md b/source/basic/loop/README.md index 2e377b27a0..8a61ffae6f 100644 --- a/source/basic/loop/README.md +++ b/source/basic/loop/README.md @@ -305,7 +305,8 @@ console.log(total); // => 1 -オブジェクトに対して列挙を行うには、`Object.keys()`、`Object.values()`、`Object.entries()`などのメソッドを利用します。 +オブジェクトに対して列挙を行うには、`Object.keys()`、`Object.values()`、`Object.entries()`などのメソッドが利用できます。 + 先ほどのオブジェクトのキーと値を列挙するには次のように書くことができます。 `Object.keys()`は`object`のプロパティ名の配列を返します。 From 50e4afd241d1b32fb1bb76e019235e0c96fd5ea1 Mon Sep 17 00:00:00 2001 From: azu Date: Tue, 19 Jul 2016 21:42:31 +0900 Subject: [PATCH 7/9] =?UTF-8?q?refactor(loop):=20=E5=95=8F=E9=A1=8C?= =?UTF-8?q?=E3=82=92=E6=8C=81=E3=81=A3=E3=81=A6=E3=81=84=E3=82=8B=20->=20?= =?UTF-8?q?=E5=88=A5=E3=81=AE=E6=96=B9=E6=B3=95=E3=82=92=E8=80=83=E3=81=88?= =?UTF-8?q?=E3=82=8B=E3=81=A8=E3=81=84=E3=81=86=E6=B5=81=E3=82=8C=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/basic/loop/README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/basic/loop/README.md b/source/basic/loop/README.md index 8a61ffae6f..dda631aeaf 100644 --- a/source/basic/loop/README.md +++ b/source/basic/loop/README.md @@ -282,8 +282,7 @@ for (var key in object) { // key:c, value:3 ``` -オブジェクトに対する反復処理を行うのにfor...in文は有用に見えますが、 -多くの問題を持っているため、使うことを避けたほうがよいでしょう。 +オブジェクトに対する反復処理のためにfor...in文は有用に見えますが、多くの問題を持っています。 for...in文は配列オブジェクトに対しても利用できますが、期待した結果にはなりません。 次のコードでは、配列の要素が列挙されそうですが、実際には配列の添字が列挙されます。 @@ -300,14 +299,14 @@ console.log(total); // => 1 配列の内容に対して反復処理を行う場合は、for文や`forEach`メソッド、後述するfor...of文を使うべきでしょう。 -また、オブジェクトに対してもfor...in文はプロトタイプチェーンにより意図しない挙動を起こすことがあります。 +また、オブジェクトに対してもfor...in文は、プロトタイプチェーンにより意図しない挙動を起こすことがあります。 プロトタイプチェーンについては第n章で詳しく解説します。 -オブジェクトに対して列挙を行うには、`Object.keys()`、`Object.values()`、`Object.entries()`などのメソッドが利用できます。 +オブジェクトのプロパティを列挙するには、`Object.keys()`、`Object.values()`、`Object.entries()`などのメソッドが利用できます。 -先ほどのオブジェクトのキーと値を列挙するには次のように書くことができます。 +先ほどの例と同じ方法で、オブジェクトのキーと値を列挙するコードは次のように書くことができます。 `Object.keys()`は`object`のプロパティ名の配列を返します。 ```js From e19c7313c93735bdea5ba279a6b2a8d137e6aeaf Mon Sep 17 00:00:00 2001 From: azu Date: Tue, 19 Jul 2016 22:01:52 +0900 Subject: [PATCH 8/9] =?UTF-8?q?refactor(loop):=20for...in=20=E3=82=AA?= =?UTF-8?q?=E3=83=96=E3=82=B8=E3=82=A7=E3=82=AF=E3=83=88=20->=20=E9=85=8D?= =?UTF-8?q?=E5=88=97=E3=81=AE=E9=A0=86=E7=95=AA=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/basic/loop/README.md | 44 ++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/source/basic/loop/README.md b/source/basic/loop/README.md index dda631aeaf..9439d82116 100644 --- a/source/basic/loop/README.md +++ b/source/basic/loop/README.md @@ -284,30 +284,18 @@ for (var key in object) { オブジェクトに対する反復処理のためにfor...in文は有用に見えますが、多くの問題を持っています。 -for...in文は配列オブジェクトに対しても利用できますが、期待した結果にはなりません。 -次のコードでは、配列の要素が列挙されそうですが、実際には配列の添字が列挙されます。 -つまり、配列の添字は0から始まるため、0、1という値が順番に`num`へと代入されます。 - -```js -var numbers = [5, 10]; -var total = 0; -for (var num in numbers) { - total += num; -} -console.log(total); // => 1 -``` +JavaScriptでは、オブジェクトは何らかのオブジェクトを継承しています。 +for...in文は、対象となるオブジェクトのプロパティを列挙する場合、すべての親オブジェクトまで探索し列挙します。 +そのため、オブジェクト自身が持っていないプロパティも列挙されてしまうことがあります。 -配列の内容に対して反復処理を行う場合は、for文や`forEach`メソッド、後述するfor...of文を使うべきでしょう。 - -また、オブジェクトに対してもfor...in文は、プロトタイプチェーンにより意図しない挙動を起こすことがあります。 -プロトタイプチェーンについては第n章で詳しく解説します。 +この仕組みをプロトタイプチェーンといいますが、詳しくは第n章で解説します。 -オブジェクトのプロパティを列挙するには、`Object.keys()`、`Object.values()`、`Object.entries()`などのメソッドが利用できます。 +安全にオブジェクトのプロパティを列挙するには、`Object.keys()`、`Object.values()`、`Object.entries()`などのメソッドが利用できます。 -先ほどの例と同じ方法で、オブジェクトのキーと値を列挙するコードは次のように書くことができます。 -`Object.keys()`は`object`のプロパティ名の配列を返します。 +先ほどの例は、オブジェクトのキーと値を列挙するコードは次のように書くことができます。 +`Object.keys()`は`object`自身がもつプロパティ名の配列を返すため、親オブジェクトのプロパティは列挙されません。 ```js var object = { @@ -324,7 +312,23 @@ Object.keys(object).forEach(key => { // key:c, value:3 ``` -for...in文は正しく扱うのが難しいですが、代わりとなる手段が豊富にあります。 +また、for...in文は配列オブジェクトに対しても利用できますが、こちらも期待した結果にはなりません。 + +次のコードでは、配列の要素が列挙されそうですが、実際には配列の添字が列挙されます。 +つまり、配列の添字は0から始まるため、0、1という値が順番に`num`へと代入されます。 + +```js +var numbers = [5, 10]; +var total = 0; +for (var num in numbers) { + total += num; +} +console.log(total); // => 1 +``` + +配列の内容に対して反復処理を行う場合は、for文や`forEach`メソッド、後述するfor...of文を使うべきでしょう。 + +このようにfor...in文は正しく扱うのが難しいですが、代わりとなる手段が豊富にあります。 そのため、for...in文を使うことよりも他の方法を考えた方がよいでしょう。 ## [コラム] `let`ではなく`const`で反復処理をする From c2c7e433b2e3de6d635e4628a24ff4480b14ccce Mon Sep 17 00:00:00 2001 From: azu Date: Wed, 20 Jul 2016 09:11:34 +0900 Subject: [PATCH 9/9] =?UTF-8?q?chore(loop):=20=E5=88=B6=E5=BE=A1=E6=96=87?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 - source/basic/loop/README.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 17baa98552..820148800b 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "babel-preset-power-assert": "^1.0.0", "babel-register": "^6.7.2", "eslint": "^3.0.0", - "eslint-plugin-markdown": "^1.0.0-beta.2", "gitbook-cli": "^2.1.2", "gitbook-plugin-canonical-link": "^2.0.2", "gitbook-plugin-edit-link": "^2.0.2", diff --git a/source/basic/loop/README.md b/source/basic/loop/README.md index 9439d82116..06d2408302 100644 --- a/source/basic/loop/README.md +++ b/source/basic/loop/README.md @@ -6,7 +6,7 @@ author: azu プログラミングにおいて、同じ処理を繰り返すために同じコードを必要はありません。 ループや再帰呼び出し、イテレータなどを使い、反復処理は抽象化します。 -ここでは、もっとも基本的な反復処理と反復処理から抜ける制御文について学んでいきます。 +ここでは、もっとも基本的な反復処理と制御文について学んでいきます。 ## while文