読者です 読者をやめる 読者になる 読者になる

Javascriptでオブジェクトの出身(クラス)を調べる(instanceof演算子)

Javascript

例えば、次のように配列を生成し、
instanceofに同じウィンドウのArrayクラスを指定すると、
結果はtrueになります。

// ChromeのJavascript Consoleで実行
> var a = [1, 2, 3, 4, 5];
undefined
> a instanceof Array
true

しかし、instanceofに別ウィンドウのArrayクラスに指定すると、
falseになります。

> var a = [1, 2, 3, 4, 5];
undefined
> var w = window.open("");
undefined
> a instanceof w.Array 

たとえ、名前が同じクラス(constructor)のオブジェクトでも、
ウインドウが違ったら、出身が違うオブジェクトになるということですね。

では、クラスの名前(と、できれば中身まで)が同じなら、ウインドウ区別なく
同じ出身にしたい場合、どうすればいいか?

配列オブジェクトの場合、
ECMAScript5をサポートする環境(最新ブラウザ、NodeJSなど)なら、
Array.isArrayという関数を使えばいいです。

次のコードを見ますと、配列aに対して、同じウインドウ上でも、別のウインドウ上でも
isArray関数はtrueを返すことが分かります。

> var a = [1, 2, 3, 4, 5];
undefined
> var w = window.open(""); // 別ウインドウ
undefined
> Array.isArray(a);
true
> w.Array.isArray(a);
true

Array以外のオブジェクトについてはどうすればいいか?
正解は分かりませんが、オブジェクトのconstructor.name属性を調べれば、
大体は対応できると思います。

> var w = window.open("");
undefined
> w.a = [1, 2, 3, 4];
[1, 2, 3, 4]
> w.a.constructor.name === "Array"
true

ただ、文字列ベースの比較なので、中身が偽者の場合、
仕方がありません。
しかし、意図的に偽者を作らない限り、また、セキュリティ(XSS)の脆弱性がない限り、
上記の方法で問題ないと思います。

そもそも、最近、別ウインドウを開くブラウザアプリは、
あまり見なくなったので、いらない内容かも?とも思いましたが、
いざそういうケースに遭うと、面倒なので、この記事を書きました。

この本(Effective Javavscript)が参考になりました。

Effective JavaScript JavaScriptを使うときに知っておきたい68の冴えたやり方

Effective JavaScript JavaScriptを使うときに知っておきたい68の冴えたやり方