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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

Q&A

解決済

4回答

4097閲覧

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

miu_ras

総合スコア902

JavaScript

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

2グッド

1クリップ

投稿2016/09/10 04:34

編集2016/09/16 01:33

数値や文字列で、明示的にオブジェクト型を使う意味を教えてください。

つまり

JavaScript

1var v = 1;

ではなく、

JavaScript

1var v = new Number(1);

とする意義についてです。

私の今の考えとしては特に意義などなく、オブジェクト型なんていらないんじゃないかと思っています。ただ、用意されているということは何かしら使い分けると意味のあるケースもあるのかもしれないと思っています。

両者の違いとしては、typeofの結果などが異なるには異なります。前者はnumber、後者がobjectです。そこが違って困ることがあるのかわかりません。むしろ、すべてnumberと評価された方が扱いやすいと思うのに、と思ってしまいます。

言うまでもないことですが、プリミティブ型でも明示的にオブジェクトが作成されるので、メソッドやプロパティへのアクセスも問題ありません。

あえて絞り出すと、オブジェクト型にすることにより、独自のプロパティを持たせ状態を保持することが可能になりますが、そんな使い方をしている例をみたことがありませんし、クソコードに感じます。

…と考えていくと、オブジェクト型を使うことのメリットもしくは意義が思い浮かびませんでした。

数値や文字列で、明示的にオブジェクト型を使う意味を教えてください。
よろしくお願いします。

###補足情報

型変換の話をされる方がいらっしゃいましたので、念のため書いておきます。

JavaScript

1var n = "12.34"; 2console.log(typeof Number(n)); 3console.log(typeof Number.parseInt(n)); 4console.log(typeof Number.parseFloat(n));

上記はすべてnumberです。型変換をするだけならこれで十分ではないかと思います。一方、下記はobjectです。new演算子を使って明示的にインスタンスを作成することにより、はじめてobjectになります。

JavaScript

1console.log(typeof new Number(n));

ここまでは知っていることを前提として、「new Number」と書かなければならないケースがあるのか、それは具体的にどのようなケースかというのが質問の主旨です。

mit0223, maisumakun👍を押しています

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2016/09/10 04:55

補足願います。 new Number(1) みたいなコードが実際に使われているところを見たことがないのですが、どこで使われていましたか?
miu_ras

2016/09/10 05:02

どこでって…。私も見たことはありませんよ。 用意されている文法の話です。
Lhankor_Mhy

2016/09/10 05:12

?? 文法の話とのことですが、たとえば、Number('1')みたいな使い方については否定されないですよね? ということはNumber(1)という現在は存在しないコードが書かれる可能性があるから「このような文法は無意味だ」とおっしゃってるんですか? 
miu_ras

2016/09/10 07:36

質問を一度きちんと読んでください。 「数値や文字列で、明示的にオブジェクト型を使う意味」これを教えてくれというのが質問です。 主張をしているわけではないのです。質問をしているのです。まずはその段階から理解していただきたいです。
guest

回答4

0

ベストアンサー

前提

多くは Number 型の方が有用だと思います。
あえて Object 型(プリミティブラッパーオブジェクト)のメリットを挙げると次のようになります。

WeakMap の引数に指定できる

JavaScript

1var wm = new WeakMap; 2 3function a () { 4 var number = new Number(1); 5 wm.set(number, 'hoge'); 6 7 console.log(wm.get(number)); // "hoge" 8} 9 10function b () { 11 // 関数b のスコープに number がないので wm.get(number) を呼び出せない 12} 13 14a(); 15b();

プロパティを書き換えられる

Object 型なので任意のプロパティを持てますし、既知のプロパティを書き換えることが出来ます。

Reference 型である

Object 型は Reference 型としての性質を持ちます。
Number#valueOf を書き換える事で疑似的にプリミティブ値をコントロールできます。
(ただし、内部プロパティは変わっていないので [[PrimitiveValue]] は 1 のままです。)

JavaScript

1var number = new Number(1); 2console.log(number); 3number.valueOf = function valueOf () { 4 return 2; 5} 6console.log(number); // Number {[[PrimitiveValue]]: 1} 7console.log(number.valueOf()); // 2 8console.log('' + number); // "2" 9console.log(number * 2); // 4

結論

極論をいえば、new Number(1)1 か、は大した問題ではないと思います。
ECMAScript 6 ではどちらの場合でも正常に動作するように設計されています。

JavaScript

1console.log(Math.max(new Number(1), new Number(3), new Number(5))); // 5 2console.log(Math.max(1, 3, 5)); // 5

Re: miu_ras さん

投稿2016/09/12 14:38

編集2016/09/12 14:42
think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miu_ras

2016/09/14 16:27

基本的にはないと考えていいようですね。 WeakMapでは明確に差が出るのですね。 参考になりました。ありがとうございました
think49

2016/09/14 22:39 編集

> 基本的にはないと考えていいようですね。 差はありますが、(基本的には)どちらの書き方であっても正常動作するコードが望ましいと思います。 あくまで基本的なので、例外的に「WeakMap」や「参照の性質を持たせたい時」には Object 型を使う価値があるかもしれない、とも思います。 どこかで聞いた事がありますが、「使える球は最後まで取っておく主義」というのがありまして、私もそれに賛同します。
guest

0

Number JavaScript オブジェクトは、数値に作用するラッパーオブジェクトです。MDN
Number オブジェクトの明示的な作成が必要になることはほとんどありません。MSDN

マニュアルにもこのように書かれていますし、数値をNumberのインスタンスとして生成するコードを記述する意味は無いと思います。
ただ、Numberそのものが不要かというと、もし無ければ「str = 1 + ' day';」等の場合に内部で「str = new Number(1).toString() + ' day';」のように処理されて文字列型への自動変換とかされているものがなくなると言うことだと思いますし、そういう意味では必要かなと思います。

投稿2016/09/10 06:35

hirohiro

総合スコア2068

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miu_ras

2016/09/12 13:20

後半はちょっとわからなかったのですが、 基本的には意味はないということですね。ありがとうございました
hirohiro

2016/09/13 00:40 編集

ラッパーオブジェクトというのはjavascriptが実行時に必要に応じて自動的に生成して使うオブジェクトです。 本来数値の「1」と文字列の「”1”」はメモリ上のデータが異なるので「1+"文字列"」は実行不可能でエラーになるはずですが、javascriptが勝手に「new Number(1).toString()」として文字列の「1」を生み出し問題を回避しています。 このとき生み出されたNumberオブジェクトは変数に格納されないので、利用後すぐに破棄されます。 つまりは、明示的に記述して使いわけ無くてもjavascriptがよろしくやってくれるので、大抵のケースでは無理する意味は無い、といったようなことです。
think49

2016/09/13 01:54

> javascriptが勝手に「new Number(1).toString()」として文字列の「1」を生み出し問題を回避しています。 これは違います。 「1 + "文字列"」を評価する場合、1 は ToPrimitive -> ToString の型変換を経て String 型に変換されますので Object 型に変換するステップがありません。 http://www.ecma-international.org/ecma-262/6.0/#sec-addition-operator-plus 内部的にプリミティブラッパーオブジェクトに変換される代表的な動作はプロパティアクセス演算子を使う場合ですね。 http://www.ecma-international.org/ecma-262/6.0/#sec-property-accessors (1).toString(); // "1" プロパティは Object 型のみが持てますが、Number 型は一時的に Object 型に変換する事でプロパティが存在するかのように振る舞います。
hirohiro

2016/09/13 03:43 編集

おお、そうなのですね。ありがとうございます。英語苦手なのでリンク先を正しく把握できていませんが、後ほど読んで見ます。 miu_rasさん間違ったこと書いてたみたいですみません。 > プロパティアクセス演算子を使う場合ですね。  ’world’.slice(1,3) こんな時なんですかね。 とすると数値の場合大抵のケースではラッパーオブジェクトすら使われないんですね。 > 1 は ToPrimitive -> ToString の型変換を経て String 型に変換 このToStringは「Abstract Operations」(抽象操作?継承用?)とありますが、何かのオブジェクトのメソッドというわけではないのですか?ToStringがグローバルオブジェクトのメソッドでプリミティブはそのプロパティということなのでしょうか?
think49

2016/09/13 05:08 編集

To: hirohiro さん > このToStringは「Abstract Operations」(抽象操作?継承用?)とありますが、何かのオブジェクトのメソッドというわけではないのですか? ECMAScript では外面的には隠された部分で共通処理を定義しており、ToString はいってみれば「String 型に変換する private method」のようなものです。 ECMAScript は型付き言語ではありませんが。引数に期待する型はある程度決まっているので ToString や ToObject のような型変換処理が初めの方で入る場合が多いですね。 http://www.ecma-international.org/ecma-262/6.0/#sec-type-conversion また、特定のデータに Internal Methods や Internal Slots が埋め込まれている場合があり、こちらも直接的に呼び出すことは出来ません。 http://www.ecma-international.org/ecma-262/6.0/#sec-object-internal-methods-and-internal-slots ちなみに、ToString は `String()` が内部的に呼び出しています。 http://www.ecma-international.org/ecma-262/6.0/#sec-string-constructor-string-value `ToObject` は `Object()` が内部的に呼び出しています(null, undefined 用の例外処理が走るので完全に同じではありません)。 http://www.ecma-international.org/ecma-262/6.0/#sec-object-value > ToStringがグローバルオブジェクトのメソッドでプリミティブはそのプロパティということなのでしょうか? new Number(1); を実行した場合、[[NumberData]] internal slot に 1 が代入されますが、この値は直接参照する方法がない為、後から書き換える事は不可能です。 http://www.ecma-international.org/ecma-262/6.0/#sec-number-constructor ただし、Number#valueOfでプリミティブ値を取得している仕組みから valueOf 関数を書き換える事で間接的にプリミティブ値を書き換えているかのように振る舞う事が可能です。 (詳しくは私の回答の「Reference 型である」を参照してください。)
guest

0

プログラム内に直接数値を入力できる場合の意義は薄いですが、何かから取得したもの(文字か数値か不確定)を変数に代入するケースだと使いどころがあるかもしれません。
new演算子を使わない、単なる型変換をしたい場合に使うケースはなくはないです(もっとほかの書き方がありますが)。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Number

追記

Numberオブジェクトのプロトタイプに、Number型用の関数が定義(toString等)されています。
これら関数を定義するために必要であると思います。

投稿2016/09/14 17:12

編集2016/09/15 01:09
yamato_hikawa

総合スコア2092

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mpyw

2016/09/14 18:27

Javaの場合はごもっともだと思いますが,JavaScriptの場合は型を束縛する配列が存在しないので,少しミスマッチな回答に思えました.
miu_ras

2016/09/16 01:37

ありがとうございました
guest

0

関数としては必要ですがインスタンスを生成する意味はないですよね。

###MDNのNumberの説明文

Number オブジェクトの主な用途は:
引数が数に変換できない場合、NaN を返します。
非コンストラクタコンテキスト (すなわち、new 演算子なし) では、型変換を行うために使われます。

とあります。型は置いといて両者結果は同じですって意味になりますね。結果は同じか。。。

javascript

1var num = new Number("10n"); 2var num2 = Number("10n"); 3 4console.log(num.valueOf()); // NaN 5console.log(num2); //NaN

###結論 Numberのインスタンス化いらね

  1. 静的に読み出せるならいらね。Number.isNaN()とかで呼び出せる。
  2. 数字として扱いたいだけなのにオブジェクト型になるからいらね。

<<追記>>
ちなみにNumber.isNaN()を例題に出したのはグローバル関数のisNaN()と少し挙動が違うからです。parseInt()など一部はグローバル関数のparseInt()などと等価です。

投稿2016/09/10 05:51

編集2016/09/10 07:13
IShix

総合スコア1724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miu_ras

2016/09/10 07:50

基本的には「意味はない」「いらない」という方向のご回答ですね。 特に引数に数値を指定するのなら全く不要、ただし、数値ではない値を指定すると型変換するので、その点で少し意味があるという感じですかね。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問