質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • JavaScript

    16440questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • ECMAScript

    120questions

    ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

  • foreach

    69questions

    foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

JavaScript - forEach構文について

解決済

回答 4

投稿

  • 評価
  • クリップ 1
  • VIEW 643

balls

score 18

現在、JavaScriptを学習している者です。
下記コードですが、JavaScript部分のforEach構文ですが、何をやっているのかは大体分かるのですが、どうしてこういう書き方をするのかがよく分かりません。

inputs.forEach(input => input.addEventListener('change', handleUpdate));


質問内容ですが、下記のとおりです。
1、そもそもjQueryでないノーマルなjavascriptで、nodeNameの「input」がどうしてそのまま書けるのだろうと疑問です。

2、あと、=> は確か無名関数の書き方と記憶しているのですが上記コードは具体的にどのようなことをやっているのでしょうか?

全体のコードは下記のとおりです。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Scoped CSS Variables and JS</title>
</head>
<body>
  <h2>Update CSS Variables with <span class='hl'>JS</span></h2>

  <div class="controls">
    <label for="spacing">Spacing:</label>
    <input id="spacing" type="range" name="spacing" min="10" max="200" value="10" data-sizing="px">

    <label for="blur">Blur:</label>
    <input id="blur" type="range" name="blur" min="0" max="25" value="10" data-sizing="px">

    <label for="base">Base Color</label>
    <input id="base" type="color" name="base" value="#ffc600">
  </div>

  <img src="https://source.unsplash.com/7bwQXzbF6KE/800x500">
:root {
      --base: #ffc600;
      --spacing: 10px;
      --blur: 10px;
    }

    img {
      padding: var(--spacing);
      background: var(--base);
      filter: blur(var(--blur));
    }

    h1 {
      color: var(--base);
    }

    body {
      text-align: center;
      background: #193549;
      color: white;
      font-family: 'helvetica neue', sans-serif;
      font-weight: 100;
      font-size: 50px;
    }

    .controls {
      margin-bottom: 50px;
    }

    input {
      width:100px;
    }
const inputs = document.querySelectorAll('.controls input');

    function handleUpdate() {
      const suffix = this.dataset.sizing || '';
      //console.log(this.name);
      document.documentElement.style.setProperty(`--${this.name}`,this.value + suffix);
    }

    console.log(inputs);
    inputs.forEach(input => input.addEventListener('change', handleUpdate));
    inputs.forEach(input => input.addEventListener('mousemove', handleUpdate));
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+3

1、そもそもjQueryでないノーマルなjavascriptで、nodeNameの「input」がどうしてそのまま書けるのだろうと疑問です。

ここでのinput単なる引数です。特にnodeNameとしての意味があるわけではありません。

2、あと、=> は確か無名関数の書き方と記憶しているのですが上記コードは具体的にどのようなことをやっているのでしょうか?

単なる関数に書き直すと、以下のようになります。

inputs.forEach(function(input){
  return input.addEventListener('change', handleUpdate)
});

NodeList.prototype.forEachArray.prototype.forEachと同様の機能で、「各要素について引数の関数を呼び出す」という意味です。returnしていますが、forEachは返り値を見ないので特に意味はありません(アロー関数の都合です)。

なお、NodeList.prototype.forEachはIE 11、iOS 9、Firefox 49以下では未対応なので、ターゲットを絞れる環境以外では実用するには少々早い気もします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+2

XXX => 処理という書き方はアロー関数と呼ばれるものです。
以下の2つは概ね同じことを指しています。

inputs.forEach(function(input) {input.addEventListener('change', handleUpdate);});

inputs.foreach(input => input.addEventListener('change', handleUpdate));

アロー関数の左辺は無名関数でいうところの「引数」を表しています。右辺は無名関数内の「処理」を表しています。なので、この左辺の「input」は別にinputエレメントを直接意味しているわけではなく、ただ単に引数の名前が「input」なだけで、このinputという変数名を「hoge」に置き換えても動作します。

アロー関数というのは書き方がいくつもあって、この書き方は「何もかもを省略して、一番短く書く方法」です。以下のアロー関数は全部同じ動作をします。

// 一番短い、「引数1個、処理1行」の場合の書き方
input => input.addEventListener('change', handleUpdate)

// 「処理が2行以上」の場合は、{}を使って処理を複数行書ける
input => {input.addEventListener('change', handleUpdate);}

// 「引数」はカッコで囲んでもよい、二個以上の引数、または1つも引数がない場合、かならずカッコが必要
(input) => input.addEventListener('change', handleUpdate)

// 一番省略しないで書いたアロー関数
(input) => {input.addEventListener('change', handleUpdate);}

公式ドキュメントにも書いてあります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/arrow_functions

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/15 13:16

    素早い回答ありがとうございます。すごいよく分かりました。

    キャンセル

  • 2018/01/15 13:20 編集

    「=> 式」で書いたアロー関数は「その式の値を返す」という意味があるので、単に中括弧で囲うだけだと意味が変わってきます。

    今回のforEachでは返り値を見ないかつ、addEventListenerの返り値そのものがundefinedなので特段の違いはありませんが、イベントハンドラなどでは「falseを返すと処理が止まる」など、返り値の有無で動作が変わる場合もあるので要注意です。

    キャンセル

+2

inputs.forEach(input => input.addEventListener('change', handleUpdate));

これはれっきとしたネイティブJavaScriptの構文です。

forEachはArray.prototype.forEachとして定義されているリスト操作のメソッドです。

本文の下部ではdocument.querySelectorAllの戻り値がNodeListなので、
実際にはNodeList.prototype.forEachとして定義されていますが、使い方や意味はほぼ同じです。

使い方はこんな感じで、for文のように配列を取り出して1個ずつ処理していきます。

[1, 2, 3].forEach(function (it) {
  console.log(it);
});
// 1
// 2
// 3

// ほぼ同様の動作をfor...ofで再現してみた。
// for...ofに対応するのはiterableなもののみでNodeListは使えるかどうか知らないので試してみてね。
for (let it of [1, 2, 3]) {
  console.log(it);
}

=>はアロー関数と呼ばれるES2015で実装された書き方です。
無名関数を簡素に書く事が出来ます。

// この2つのコードはほぼ等価
inputs.forEach(input => input.addEventListener('change', handleUpdate));

inputs.forEach(function(input){
  // forEachは戻り値を捨てるのでreturnする意味はないが、
  // アロー関数の{}を省略した場合、式全体が戻り値になるので動作を揃える為に記述
  return input.addEventListener('change', handleUpdate));
})

どっちの方が簡素で読みやすいでしょうか?
まぁ前者ですね、これが存在意義です。

アロー関数と無名関数をほぼ等価と表現したのにはわけがあって、
アロー関数では関数内で自動的に行われるthisやargumentsが生成されません。
めったにthisやargumentsに頼るべき場面がないので忘れがちですが、極稀にハマるので注意してください。

1、そもそもjQueryでないノーマルなjavascriptで、nodeNameの「input」がどうしてそのまま書けるのだろうと疑問です。

document.querySelectorとdocument.querySelectorAllの勘違いですかね?
document.querySelectorの戻り値はElementです。
document.querySelectorAllの戻り値はElementを束ねたNodeListという配列もどきのオブジェクトです。

NodeListはNodeList.prototype.forEachをプロトタイプメソッドとして所持しているのでforEachは正しく動作します。

jQueryはセレクタ文字列を渡してDOMの一覧を受け取る場合、
jQueryオブジェクトという大量のプロトタイプメソッドを持つ配列もどきが返ってきます。
なのでNodeListと一部似たような操作が出来るわけです。
まぁ、NodeListにはforEachくらいしか見るものがないですけど…

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

.forEach()は構文ではなく関数と考えた方がいいと思いますよ。この関数の引数が無名関数です。

hoge => alert(hoge+"fug")みたいに書いた時、この関数の引数がhogeになります。

ですからinputhogeとかに変えても普通に動作するはずです。inputはnodeNameではありません。

では無名関数の引数には何が入るか、ですが、それは順に配列等に含まれる各要素現在のインデックス配列そのものです。渡す関数で省略されている場合は受け取りません。今回は配列に含まれる各要素のみ引数として受け取っています。

無名関数内ではその各要素ごとに無名関数内の処理を行っています。

それが質問者様が挙げられたコードの内容です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    16440questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • ECMAScript

    120questions

    ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

  • foreach

    69questions

    foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。