あらまし
haragurai-is-bad氏が、記事中でArray.indexOf()
メソッドをポリフィルしてExtendScriptに実装していらした。
haraguai-is-bad.hatenablog.com
実はポリフィルしてた
記事のコメントにも書いたとおり、僕はArray.some()
メソッドをポリフィルしています。
使用例
使い方としてはこんな感じ。
選択したオブジェクトが何者かによって処理を変えるサンプルです。
//@include "array_some_jsxinc" // 適宜インクルードする var doc = app.activeDocument; var sel = doc.selection[0]; var acceptClasses = [Text, Word, Character, Line, Paragraph]; // 選択を許可するインスタンス if (acceptClasses.some(function (elem) { return (sel instanceof elem); })) { $.writeln("許可されたインスタンスです"); } else { $.writeln("このオブジェクトのインスタンスは "+sel.constructor.name+" です"); }
Array.some()
メソッドの基本
基本はMDNを参照。
ここにあるようにArray.some()
メソッド自体の引数は最大で2つ(コールバック関数とthis
オブジェクト)、コールバック関数の引数が最大で3つです。
ES3の仕様でコールバック関数を書くのがめちゃくちゃダサいし冗長なのですが*1、それは仕方ないので諦めます。泥臭くfunction文書いてください。
MDNを参照していただくともうそれ以上の情報はないんですが一応紹介しておくと、コールバック関数の第一引数に配列の各要素が取り出されます。その各要素に対して、コールバック関数が適用されるようなイメージです。
先のサンプルコードでいうと、
function (elem) { return (sel instanceof elem); }
コールバック関数はこの部分。配列acceptClasses
の各要素が変数elem
に引っ張り出されて、このコールバック関数を実行します。配列の最初の要素はText
なので、sel instanceof Text
が評価されます。これがfalse
であれば次の要素(Word
)が…という具合です。
その間に一度でもtrue
が帰ってくればArray.some()
メソッド自体がtrue
を返す、というわけですね。
応用してみる?
/** * 選択したオブジェクト群に1つでも特定のテキストが含まれるかどうか */ //@include "array_some_jsxinc" var doc = app.activeDocument; var sel = doc.selection; var re = /^\d+/; // 先頭が数字で始まる if (sel.some(function (elem) { return elem.hasOwnProperty("contents") && re.test(elem.contents); })) { $.writeln("正規表現 " + re.source + " がマッチするテキストがあります"); } else { $.writeln("マッチしません"); }
こんな感じで、配列の中の特定のプロパティを参照することもできます。使い方によっては非常に便利なのでお試しあれ〜
*1:MDNに掲載されているアロー関数のシンプルさったらない。泣ける