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

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

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

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

Q&A

解決済

6回答

8838閲覧

フォームで受け取った数値は必ず文字列になる? 文字列を数値にする目的でevalを使用してはいけない?

re97

総合スコア208

JavaScript

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

2グッド

1クリップ

投稿2016/04/03 04:59

あるコードで、フォームで受け取った数値を(数値にする目的でだと思うのですが)、evalしている箇所があるのですが、

javascript

1eval(フォームで受け取った数値);

質問1
・フォームで受け取った数値は必ず文字列になるのでしょうか?


質問2
・仮にフォームで受け取った数値でなかった場合、数値にする目的で文字列をevalしても良いでしょうか?

javascript

1typeof '100'; //"string" 2typeof eval('100'); //"number"

質問3
・下記はどういう意味でしょうか?

算術式を評価する目的で eval() を呼び出してはいけません。JavaScript は算術式を自動的に評価します

日本語

Do not call eval() to evaluate an arithmetic expression; JavaScript evaluates arithmetic expressions automatically.

英語

M_Norihiro, ikuwow👍を押しています

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

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

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

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

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

guest

回答6

0

フォームで受け取った数値をeval()、質問3に関して

そんなコード使わないほうが良いでしょう。
eval()というのは引数に渡した値をJavaScriptコードとして動的に実行します
つまるところ、コードを書けば、それが実行できるということです。

もし、悪意のあるコードを記述すれば、(eval()した後にその値をどのように処理するかにもよりますが、処理によっては)重大なXSS脆弱性を生むことにもなります。

参考リンク MDN eval()
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/eval

input要素などに入力された値に対してJavaScriptで処理を行いたい場合はvalueを取得して…という方法で可能ですので、わざわざeval()する必要性は皆無です。

質問2に関して

JavaScriptのデータ型の書式について少し誤解があるのかもしれません。

'1' //クォーテーションで囲むと文字列です 1 //数値は何も囲いません

受け取った値に対して型変換したい場合は、それぞれ専用のメソッドがあります。eval()ではなくそれらを利用しましょう。
また、受け取った値が必ず文字列か?と言われると、同じように取得にどのような処理をしているかによって変わってきます。(ただ、型変換等は基本としてやるかな…?と思います。)

この辺りも一緒に確認されてみてはいかがでしょう?

  • データ型 (JavaScript)

https://msdn.microsoft.com/ja-jp/library/7wkd9z69(v=vs.94).aspx

  • 型変換のいろいろ

http://qiita.com/zawascript/items/a25eaf7a222ac3671275

投稿2016/04/03 05:48

manabufukai

総合スコア700

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

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

re97

2016/04/04 02:36

・回答&リンク提示ありがとうございました ・型変換難しいですね…
manabufukai

2016/04/05 17:15 編集

よくよく考えるとあまり質問への答えになっていませんでしたね…失礼いたしました。。 型変換、理屈が分かると簡単なことだと思いますよ! ただ、この部分が曖昧だと算術の際に予期しないエラーをまねくのでその点だけ注意というところでしょうか。 例えばJavaScriptの場合、文字列と数値を+(加算)すると数値が文字列に型変換されてしまうという特徴があります。(エラーにならない) なので var a = 'これは文字列'; var b = 2; a + b = 'これは文字列2' になってしまいます。(加算ではなく文字列の連結) ここで、もし数値どうしの計算をさせたいのに、文字列扱いで数字を変数へ格納してしまうと、下記のようなことが起こります。 var a = '3'; var b = 2; console.log( a + b ) //32 (※string) 本当ならば「5」という結果を欲しているのに、まったく違う答えが返ってきます。 こういったことにならないように、(このケースなら)文字列をあらかじめNumber()等で型変換しておくと良い、くらいの感じかなと。
re97

2016/04/06 02:48

コメントありがとうございました
guest

0

解決済みのようですが、やや誤解があるようなので補足します。
「フォームで受け取った値」を「input 要素ノードのプロパティを参照した場合」だとして、String 型に限定されてはいません。

  • input.valueString
  • input.valueAsNumberNumber
  • input.valueAsDateObject 型 (new Date)

HTML

1<input type="number" value="1"> 2<input type="date" value="2016-04-06"> 3<input type="text" value="2"> 4 5<script type="text/javascript"> 6'use strict'; 7console.log(typeof document.querySelector('input[type=number]').valueAsNumber); // "number" 8console.log(typeof document.querySelector('input[type=date]').valueAsDate); // "object" 9console.log(Object.prototype.toString.call(document.querySelector('input[type=date]').valueAsDate)); // "[object Date]" 10console.log(typeof document.querySelector('input[type=text]').valueAsNumber); // "number" 11</script>

Re: re97 さん

投稿2016/04/05 18:36

編集2016/04/05 18:37
think49

総合スコア18162

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

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

re97

2016/04/06 03:07

・回答ありがとうございました ・「GETやPOSTで送信された数値を受け取った時点」では、常に文字列になる、という認識で合っているでしょうか? ・回答内容は、数値で送信したつもりでも異なる場合があるということ? それとも、「フォームで受け取った値」を「input 要素」へセットした場合(?)、Number型で受け取ることも可能ということでしょうか? ・valueAsNumberは、input要素にだけ適用可能なプロパティ? ・valueAsNumberのTypeにdoubleと書いてあったのですがどういう意味? 適用対象によってnumberにもなり得る?
think49

2016/04/06 23:44 編集

・GETやPOSTで送信された値はサーバサイドで受け取るのでクライアントサイドJavaScriptでは受け取れません。JavaScriptで参照可能なのはDOM要素への参照だけです。 ・valueAsNumberがinput要素ノード専用かは全ての要素ノードの仕様をみる必要があります。少なくない時間がかかると想われる為、その都度調べる事をお勧めします。 ・double は浮動小数点数を指します。JavaScript では Number 型と同義と解釈して問題ありません。 https://html.spec.whatwg.org/multipage/infrastructure.html#reflecting-content-attributes-in-idl-attributes
re97

2016/04/07 01:58

・コメント&リンク提示ありがとうございました
guest

0

ベストアンサー

* 質問1 ・フォームで受け取った数値は必ず文字列になるのでしょうか?

はい。文字列です。 フォームのテキストボックスに 1 をいれた場合は "1" の文字列になります。

* 質問2 ・仮にフォームで受け取った数値でなかった場合、数値にする目的で文字列をevalしても良いでしょうか?

eval() の利用は避けるべきです。
文字列 -> 整数に変換するメソッドが javascript には存在しています。

* 質問3 ・下記はどういう意味でしょうか?

算術式 (1 + 2) を計算する為に eval() を使う必要はありません。javascropt は算術式を計算する機能を持っているので。

var a = eval(1 + 2);
でなく
var a = 1 + 2;
とできるということです。
(eval は evaluate という単語(評価するという意味がある) の省略なので eval(1+2) という記述は不自然ではないが、こう書く必要はないということ)

投稿2016/04/03 09:10

katoy

総合スコア22324

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

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

re97

2016/04/04 02:31

・回答ありがとうございました ・参考になりました
guest

0

質問2に関して,JavaScript では昔から以下のような暗黙の型変換を利用したテクニックがあります。

var num_str = "100";
typeof num_str; // "string"

var num = num_str * 1;
typeof num; // "number"

var num2 = num_str - 0;
typeof num2; // "number"

数値を表す文字列に対して「*1」や「-0」のように算術を行うと,JavaScript では暗黙的に文字列を数値として扱う仕様となっています。「*1」や「-0」を使用すれば,数値の値自体は変化しないので,実質数値を表す文字列をそのまま数値として使用できます。ただし「+0」は使用できません。「+」は文字列の連結にも使用されるため,数値を表す文字列の方に影響されて「+0」とすると暗黙的に「0」の方が文字に変換されてしますからです。
また,他にも注意点があります。

  1. 数値を表す文字列の中に数値以外の文字が含まれていないことを確認してから使用すること。数値以外の文字が含まれているとエラーとなります。
  2. 算術式の評価順序によっては,正しく動作しないことがあるので,暗黙の型変換の仕様を正しく把握してから使用すること。

初心者が安易に使うべきものではないかもしれませんが,たまに見かけるので知っておいて損はないと思います。

あと,フォームで受け取った値を直接 eval() することは厳禁です。絶対やってはいけません。必ずといっていいほど脆弱性となります。

投稿2016/04/09 02:51

Lightfox

総合スコア28

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

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

re97

2016/04/10 01:21

・回答ありがとうございました >暗黙の型変換を利用したテクニック >他にも注意点があります ・初めて知りました ・こういう書き方も可能である以上、知っておかないと読めないと思いました ・参考になりました
guest

0

  1. 文字列になると思います。
  2. parseInt を使いましょう。

JavaScript

1parseInt( '100', 10 ); // 100

3は、多分こういうことかなと。

JavaScript

1var a = eval("2 + 2"); // 4 2var b = 2 + 2; // 4

JavaScript の中でも特殊な立ち位置にある eval は避けれるなら避けて、それ以外解決方法がない場合に使用する、くらいにしておいたほうが良いと思います。

投稿2016/04/03 05:58

kei344

総合スコア69407

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

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

re97

2016/04/04 02:32

・回答ありがとうございました ・参考になりました
guest

0

1.
フォームに入力される文字列が必ず数値とは限らないので、JavaScriptにかぎらず、ほとんどの言語
では普通は文字列として受け取ります。(例外もあるかもしれませんが。)

2.
(プログラムが動くという意味では)問題はないと思います。
ただし、JSは気をつけて実装しないと多くの脆弱性を生む可能性があるので、詳しくは、他の方の解答を参考にしてください。

3.
日本語がわかりづらいですね。英語の表現がわかりやすいです。算術式を引数にする使い方は推奨しないということでしょう。文字列を入れるべきということです。

Do not call eval() to evaluate an arithmetic expression

具体的にいうと、下記のような意味かと。

JavaScript

1eval("2 + 2"); // 文字列だからOK 2eval("2"); // 文字列だからOK 3× eval(2 + 2); // 算術式だからNG 4× eval(2) // 2という数値(算術式)だからNG

投稿2016/04/03 05:46

編集2016/04/03 05:59
Odacchi

総合スコア907

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

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

Odacchi

2016/04/03 06:03

manabufukaiさんの解答を受けて、一部、脆弱性に関する記述を盛り込むよう加筆修正しました。
re97

2016/04/04 02:38

・回答ありがとうございました >算術式を引数にする使い方は推奨しない ・参考になりました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問