質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • JavaScript

    16007questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

【JavaScript】プリミティブ型である文字列値とStringオブジェクトについて

解決済

回答 3

投稿

  • 評価
  • クリップ 3
  • VIEW 1,264

takenyaan

score 111

掲題の件について質問です。

プリミティブ型である文字列値とStringオブジェクトについてですが、
値がどのように格納されているのかご教示下さい。

プリミティブ型
var str = "hoge";
alert(str); // hoge

Stringオブジェクトの場合
var str = new String("hoge");
alert(str); //hoge

プリミティブ型については直観的に理解できるのですが、
オブジェクト型のStringについてコンストラクタに指定した"hoge"という値はstrオブジェクトの何に格納されるのでしょうか。
オブジェクトはプロパティとメソッドから成り立つと認識しているため、"hoge"という値にアクセスするためには、「str.プロパティ名」とする必要があるように思えるのですが。

とんちんかんな質問で申し訳ございません。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

うーんと、property と value の形で外から見えるようにできる、というだけのことであって、
必ずしも Object classを継承したからといって、内部構造がそのようになっているとは
限りません。(仕様が決まっているだけで。)

とはいえ、とりあえず for in でプロパティを見たくなるのは人情ですね。
というわけで、
var s = new String('abcde');
for (var a in s) {window.console.log(a + ":" + s[a]);}
とすると、
0:a
1:b
2:c
3:d
4:e
と返ります。文字 の配列のような見え方をしますね。では 文字列 (not object)ではどうなのでしょうか。
var s0 = String('fghij'); //newがないことに注意。
for(var a in s0) {window.console.log(a + ":" + s0[a]);}
とすると
0:f
1:g
2:h
3:i
4:j
と、同じようなものが帰ってきます。
というわけで、このレベルでの違いは for in では見えません。
#ただし、string Object では、length, "proto" といった (見えてこない)プロパティもあります。

String Objectと 文字列との違いは、
  1.  "===" による比較で結果が違うということ、
  2.  typeOf による結果が違う (文字列は "string", String Objectは "object") こと、
  3.  eval の結果が異なる (eval(String('2+2')) と eval(new String('2+2')) が違う) こと
ぐらいが目に見える 違いでしょうか。

わたしは処理系の実装までは調査しませんでしたので、この回答ではご不満かもしれません。
他の回答者の答えもご参考にしてくださいね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

こんにちは。

JavaScriptには疎いですが…。
少し調べてみた限りではtakenyaanさんの考察で合っているような気がします。

オブジェクトはプロパティとメソッドから成り立つと認識しているため、"hoge"という値にアクセスするためには、「str.プロパティ名」とする必要があるように思えるのですが。 

以下によると、文字列を得るためには、valueOfまたはtoStringを呼び出す必要があります。
http://hakuhin.jp/js/string.html

ではなぜ、alert(str); で「hoge」が得られるかと言うと、これは以下を信じるならば、alert関数が自動でtoStringしているだけなのではないでしょうか。
http://www.ajaxtower.jp/js/object_class/index3.html

なので、プリミティブと同様に扱われているように見えるところは、参照型の場合は自動的にtoStringまたはvalueOfされているのではないか、と予想します。(ここまで書いてみたものの自信がイマイチ。出所が確かな情報が欲しいですね。JavaScriptの場合はどこのサイトがよろしいのか…。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

どのようにPrimitiveValueが格納されているか回答できなくて申し訳ないのですが、
Tak1waさんの仰るとおり、Stringオブジェクトには必要に応じてtoString()やvalueOf()が行われているようですね。
var str = new String("hoge");

// StringオブジェクトであるstrのtoString, valueOfをオーバーライド
str.toString = function () {
    console.log(".toString()");
    return String.prototype.toString.call(this);
};
str.valueOf = function () {
    console.log(".valueOf()");
    return String.prototype.valueOf.call(this);
};

// toString()が呼ばれる
alert(str); // "hoge"
alert(str.toString()); // "hoge"
alert(new String(str)); // "hoge"
alert(String(str)); // "hoge"
alert(new Object(str)); // "hoge"
alert(Object(str)); // "hoge"

// valueOf()が呼ばれる
alert("" + str); // "hoge"
alert("hoge" == str); // true
alert("hoge" === str); // false
alert(+str); // NaN
alert(1 + str); // "1hoge"
alert(0 == str); // false
alert(0 < str); // false
alert(0 <= str); // false
alert(true == str); //false
alert(new Number(str)); // NaN
alert(Number(str)); // NaN
alert(new Boolean(str)); // true
alert(Boolean(str)); // true

【おまけ】 実際こんなトリッキーなコードを使うことは無いでしょうが、こんなことも出来るようですね。
var str = new String("10");

// 当たり前
alert(str); // 10
alert(+str); // 10

str.toString = function () {
    console.log(".toString()");
    return "1";
};
str.valueOf = function () {
    console.log(".valueOf()");
    return -1;
};

// !!!?
alert(str); // 1
alert(+str); // -1

alert(String.prototype.toString.call(str)); // 10
alert(String.prototype.valueOf.call(str)); // 10
なかなか奥が深いです

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/05/12 11:17

    すばらしいですね。 たしかに +str のときにvalueOf るのは 仕様通り!
    ただし、
    var so = new String("abc");
    "abc" === so.valueOf(); //true
    "abc" === +so; // false
    となり、 valueOf そのものではないようですね。

    var so = new String("123");
    123 === +so; // true
    となり、"+" の場合に valueOf したあと evalしていることが伺えます。

    わたしが 普段 valueOf を使うのは、 "===" で同一文字列かを調べるときで
    ex. sObj0.valueOf() === sObj1.valueOf()
    だけど、これは どうも コストが高い気がしてなんとなく後ろめたかったんですが、
    堂々やってもいいかもしれないと思いました。

    キャンセル

  • 2015/05/12 17:54

    コメント有難うございます。
    ご指摘の通り、valueOfの結果そのものにはならなかったですね。

    > "+" の場合に valueOf したあと evalしていることが伺えます。
    「+」演算子を使うとNumberへ変換されるため、恐らくNumber(so.valueOf())のような動作をしているのではないでしょうか(間違っていたらすみません…)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    javascript のスコープについて

    $(function(){     var self = this;     self.fuga = function(){         return 'aaaaa';    

  • 受付中

    未経験者にnullと0の違いを説明する方法

    新人にjavascriptを教えている最中ですが、 nullと0の違いがなかなか理解できないみたいです。 まったくのプログラム未経験者に伝えるにはどのように伝えれば Null

  • 解決済

    文字列や数値でオブジェクト型を使う意味

    数値や文字列で、明示的にオブジェクト型を使う意味を教えてください。 つまり var v = 1; ではなく、 var v = new Number(1);

  • 解決済

    javascriptのlengthプロパティにつきまして

    お世話になります。 var a = [5, 10]; alert(a.length); // → 2が表示される 当たり前のようにある、JSコードですが、ちょっと謎で

  • 解決済

    JavaScriptの基本的な引数の使い方につきまして

    お世話になっております。 とても基本的な部分なのですが、明確に理解をしたいので、ご存知の方がいらっしゃればご教示をお願いします。 まず例えば var dat =

  • 解決済

    アクセス式と混同?

    パーフェクトjavascriptの124pでドット演算子とブラケット演算子の違いについて説明しているところで、 なおオブジェクトリテラルのプロパティ名は次のように識別子

  • 解決済

    関数で変数作成するにはどうすればいいのか

    前提・実現したいこと javascriptで 関数testに指定した引数1の変数に、引数2の値を代入したいのですがうまくいきません。 発生している問題・エラーメッセージ Unc

  • 解決済

    JavaScriptの構文

    JavaScript勉強中のものです。 すごく基本的なことを聞いてしまいますが、 下記の構文は、どういう意味があるのでしょうか? ソースコード var hoge; (fun

同じタグがついた質問を見る

  • JavaScript

    16007questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。