最近人にプログラミングを教えるというような事があって、「オブジェクトの正体」を理解してもらおうという目的から いろんなリテラルをinstanceofにかけていました(FireFox3のFireBugで)。

  1. [1,2,3] instanceof Object // => true
  2. { a:0, b:1} instanceof Object // => true


こんな感じで。 しかし文字リテラルの挙動が期待と違っていました。

  1. "a" instanceof Object // => trueかと思いきやfalse
  2. "a" instanceof String // => trueかと思いきやfalse


ちょっと待ってほしい。 文字リテラルも文字列クラスのインスタンスですよー、なんて解説をしようと思ってたのに これじゃぁ、文字リテラルはStringオブジェクトじゃないという事になってしまう。

事実として

  1. "hoge".sub("o","a") // => "hage"


というコードが実行できるのだから、文字列リテラルがStringオブジェクトじゃないと話が合わない。だってsubメソッドはStringのインスタンスメソッドじゃないか!

結論

答えはここにありました。

Literals - MDC(文字列リテラル)

String Object - MDC #文字列リテラルは String オブジェクトとは別物

文字列リテラルの値でなら、String オブジェクトのどんなメソッドでも呼び出すことができます。JavaScript が自動的に文字列リテラルを一時的な String オブジェクトに変換し、メソッドを呼び出し、その一時的な String オブジェクトを破棄するのです。String.length プロパティを文字列リテラルで使うこともできます。

という事なんですって。

つまり、文字列リテラルの状態では確かにStringのインスタンスではないけれど、メソッドを呼び出す時はJavaScriptがStringオブジェクトに変換していると。なるほど。

ちなみにこのエントリーの内容はMozilla FireFoxでしか試していませんし、Mozillaのサイトでしか結論を見つけていませんので、他のブラウザでどうなのかは一切調べてませんので悪しからず。誰か暇な人は調べてトラバください。

Posted in javascript, 日記 at 10月 14th, 2008. No Comments.