Skip to content

Instantly share code, notes, and snippets.

@think49
Last active October 29, 2017 12:12
Show Gist options
  • Save think49/df8c54a9aa421db3b650a3c1cab9b4a9 to your computer and use it in GitHub Desktop.
Save think49/df8c54a9aa421db3b650a3c1cab9b4a9 to your computer and use it in GitHub Desktop.
nodelist-prototype-foreach.js: Web IDL 既定の NodeList.prototype.forEach の Polyfill(互換コード)

nodelist-prototype-foreach.js

概要

Web IDL 既定の NodeList.prototype.forEach の Polyfill(互換コード)を提供します。

使い方

NodeList.prototype.forEach( callbackfn [ , thisArg ] )

NodeList の index 0 から順番に走査し、第一引数に指定されたコールバック関数を呼び出し、反復処理を行います。 コールバック関数の仮引数には第一引数「現在の要素ノード」、第二引数「現在のインデックス値」、第三引数「NodeListオブジェクト」が渡されます。

document.querySelectorAll('.foo').forEach(function (element, i, nodeList) {
  console.log(element);   // nodeList[0] -> nodeList[1] -> nodeList[2] -> ...
  console.log(i);         // 0 -> 1 -> 2 -> ...
  console.log(nodeList);  // document.querySelectorAll('.foo') の返り値
});

第二引数でコールバック関数内の this 値を指定することが出来ます(オプション)。

document.querySelectorAll('.foo').forEach(function (element, i, nodeList) {
  console.log(this);  // {a: 1}
}, {a: 1});

NodeList.prototype.forEachArray.prototype.forEach とは違い、列挙可能(enumerable: true)な仕様です。従って、NodeListfor-in で走査すれば、列挙されます。

var nodeList = document.querySelectorAll('.foo'), keys = [];

for(var key in nodeList) {
  keys.push(key);
}

console.log(JSON.stringify(keys));  // ["0","1","2","3","4","5","6","7","length","item","entries","forEach","keys","values"]

参考リンク

/**
* nodelist-prototype-foreach.js
* The forEach() method of the NodeList interface calls the callback given in parameter once for each value pair in the list, in insertion order.
*
* @version 1.0.0
* @author think49
* @url https://gist.github.com/think49/df8c54a9aa421db3b650a3c1cab9b4a9
* @license http://www.opensource.org/licenses/mit-license.php (The MIT License)
* @see <a href="https://heycam.github.io/webidl/#es-forEach">3.6.9.2. forEach - Web IDL</a>
*/
'use strict';
if ((typeof NodeList === 'function' || typeof NodeList === 'object') && typeof NodeList.prototype === 'object' && typeof NodeList.prototype.forEach !== 'function') {
NodeList.prototype.forEach = function forEach (callbackfn /* [thisArg] */) { // Descriptor === {writable: true, enumerable: true, configurable: true}
var thisArg = arguments[1] || this,
i = 0,
len = this.length;
while (i < len) {
callbackfn.call(thisArg, this[i], i++, this);
}
};
}
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>test</title>
<style>
</style>
</head>
<body>
<ul>
<li class="foo">a</li>
<li class="foo">b</li>
<li class="foo">c</li>
<li class="foo">d</li>
<li class="foo">e</li>
<li class="foo">f</li>
<li class="foo">g</li>
<li class="foo">h</li>
</ul>
<script>
'use strict';
NodeList.prototype.forEach = null;
</script>
<script src="nodelist-prototype-foreach-1.0.0.js"></script>
<script>
'use strict';
var nodeList = document.querySelectorAll('.foo'),
descriptor = Object.getOwnPropertyDescriptor(NodeList.prototype, 'forEach'),
array = [], object = {};
console.assert(typeof NodeList.prototype.forEach === 'function');
console.assert(typeof nodeList.forEach === 'function');
console.assert(descriptor.writable === true);
console.assert(descriptor.enumerable === true);
console.assert(descriptor.configurable === true);
nodeList.forEach(function (element, i, nodeList) {
array[i] = element.firstChild.data;
object.nodeList = nodeList;
});
console.assert(JSON.stringify(array) === '["a","b","c","d","e","f","g","h"]');
console.assert(object.nodeList === nodeList);
array = [];
nodeList.forEach(function (element, i, nodeList) {
this[i] = element.firstChild.data;
}, array);
console.assert(JSON.stringify(array) === '["a","b","c","d","e","f","g","h"]');
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment