Help us understand the problem. What is going on with this article?

ArrayLike オブジェクトで Array.prototype 系メソッドを使用する

More than 3 years have passed since last update.

NodeList オブジェクトは Array.prototype を継承しない

querySelectorAll が返す NodeList オブジェクトは Array.prototype を継承しない為、そのままでは Array.prototype.forEach を使用できません。
そこで Function.protoype.call を利用してこれに対応するテクニックがよく使われます。

Array.prototype.forEach.call(document.querySelectorAll('p'), function (element) { console.log(element); });

よく使う機能なら関数化したい、という事でいくつか書いてみました。

(2016/12/22 15:05 追記)
@gaogao_9 さんより「HTML Living Standard では NodeList に “entries”, “forEach”, “keys”, “values” がある」との情報を頂きました。
Array.prototype.forEach とは別物ですが、使い勝手は同じだそうです。

console.log(document.querySelectorAll('p').forEach);  // function forEach() { [native code] }
console.log(document.querySelectorAll('p').forEach === Array.prototype.forEach);  // false (Google Chrome 55.0.2883.87 m の結果)

document.querySelectorAll('p').forEach(function (element, i, elements) {
  console.log(element, i, elements, this);
}, []);

Array.prototype にあるメソッド全ては存在しないので以降は Array.prototype.filter 等、他の関数を汎用化するものと置き換えて下さい。
あるいは、HTML Living Standard を実装していないブラウザ向けとお考え下さい。

汎用関数 forEach (通常版)

よく見るコードです。

function forEach (arrayLike, callbackfn) {
  return Array.prototype.forEach.call(arrayLike, callbackfn);
}

汎用関数 forEach (forEachキャッシュ版)

Array.prototype.forEach を何度も参照するのはプロパティ参照コストが無駄なのでキャッシュしました。

var forEach = (function (_forEach) {
  return function forEach (arrayLike, callbackfn) {
    return _forEach.call(arrayLike, callbackfn);
  };
}(Array.prototype.forEach));

汎用関数 forEach (forEach,callキャッシュ版)

更に Function.prototype.call もキャッシュしました。
Function.prototype.bind を利用している為、ES5 (IE9+) を要求しますが、自前で関数式を書く必要がなくなっています。

var forEach = Function.prototype.call.bind(Array.prototype.forEach);

実行サンプル

<p>test1</p>
<p>test2</p>
<p>test3</p>
<p>test4</p>
<p>test5</p>
<p>test6</p>
<script>
'use strict';
var forEach = Function.prototype.call.bind(Array.prototype.forEach);

forEach(document.querySelectorAll('p'), function (element) { console.log(element); });
</script>

参考リンク

think49
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした