変数宣言のvarアリとナシの違いや使い分けについて教えてください。
一応自分で分かっている範囲のことを書きますと、
varアリだとconfigurableがfalseになる。つまりdeleteできない(Chromeの場合。IEとFirefoxでは削除できる)。
varナシはtrueでdeleteできる。
var v1 = 1; v2 = 2; console.log(Object.keys(this).filter(function (v) {return /^v.$/.test(v)})); console.log(Object.getOwnPropertyDescriptor(this, "v1")["configurable"]); console.log(Object.getOwnPropertyDescriptor(this, "v2")["configurable"]); // Chromeでの結果。IE, Firefoxではどちらもtrue。 // ["v1", "v2"] // false // true
言い換えると
varアリは「グローバル変数」、
varナシは「グローバルオブジェクトのプロパティ」
であるということ(書籍「JavaScriptパターン」にそう書いてあった。でもそれ以上の説明はなく、本質的には違いが分かっていません)。
自分の分かる範囲では、ここだけです。もしかしたら他にも差があるかもしれませんが、ここだけだとしても、違いがあるということは意味があって差をもうけていて、何かしらの使い分けをするケースがあるのではないかと思うのですが…
だとすると「あとでdeleteしたいときにvarをつけない」とするということでしょうか?
その他、シンボルの解決に影響するとかあるのでしょうか?
質問
・上記以外に差はありますか?
・どのような使い分けをするものなのでしょうか?
よろしくお願いします。
※言うまでもないことだと思いますが、関数内でvarをつけたら関数ローカルになり、明らかに違いが出ますので比較の対象外です。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
細かい差異までは分かりませんが、最近の傾向として、
"use strict";
を用いて厳格(strict)モードで書くのが推奨されているようで、
厳格モードではvarナシはエラーとなり、そもそも使用できません。
JavaScriptとしては、varナシは互換性のために残している古い書き方で、
基本使ってはいけない扱いのようです。
厳格モードにしてvarナシは使用しない、がいいのではないでしょうか?
【追記】
MDN:varによると、
違いは、宣言した変数はグローバルオブジェクトの設定変更不可プロパティになります、宣言していない変数は設定変更可能です。
とありますので、差異は質問で既に述べられている事ぐらいしか無いようです。
投稿2015/08/19 21:47
編集2015/08/19 21:53総合スコア21737
0
ベストアンサー
ES3 の VariableStatement には DontDelete 属性という内部属性があり、var 付きで宣言した変数は delete
演算子で削除できませんでした。
(ES3 の仕様に関しては JavaScript の変数と delete 演算子: Days on the Moon が詳しい)
ES5.1 の VariableStatement ではこの規定は削除され、delete
演算子で削除できるようになりました。
(私の読む範囲ではそうですが、間違いがあったらご指摘下さい)
varアリだとconfigurableがfalseになる。つまりdeleteできない(Chromeの場合。IEとFirefoxでは削除できる)。
IE, Firefox の挙動が ES5.1 に準拠していると思われます。
・上記以外に差はありますか?
var
なしで変数宣言すると Strict Mode で ReferenceError を返します。
・どのような使い分けをするものなのでしょうか?
私なら configurable の値が何でも良いなら var
を使い、configurable の値を指定するなら Object.defineProperty を使用します。
実装の挙動差異もさることながら、configurable の値を操作するなら Object.defineProperty
を使うのが順当だと思います。
投稿2015/08/23 22:56
総合スコア18189
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/08/25 13:48
2015/08/25 16:33
2015/08/25 22:52
0
今EcmaScriptの仕様書をさらっと見てきましたがその「違い」についての言明は見つけられませんでした。言い換えればそもそも「varのない場合」についての言明がみられません。多分。要するにvarがないのはおそらく(EcmaScriptにおける)変数宣言文としてはただの文法違反です。要するに、本来実行されるべきでない「意味を持たないー意味論上解釈不能な」文です。
更に換言すればその「違い」は完全に処理系に委託されており、その違いを以ってコーディングするなどはまともなコーダーのすべきことではなかろうと思われます。
と断言してしまいましたが私は英語が苦手なのでそこまでしっかり数百ページに及ぶ仕様書を読んだわけではありません。ただ、おそらくEcma仕様外です。
んで、多分var無しのほうがconfigure==trueとなってるのはそもそもecma5以前はconfigurableという属性がそもそも存在しなかったからです。私自身ecma3でjsを勉強しましたからこのconfigurableという属性を知りませんでした。これまでは書き込みの可否、列挙の可否、再定義の可否の3種類です。
ちなみにconfigurableの規定値はfalseであり、すなわちvarなしの方もそうあるべきなのでしょうが、おそらくecma前に無茶して書かれたコードを生かそうとした結果だと思われます。
私はおいラリーの本でJSを勉強しました。厚くてお勧めです。座布団にもなります。
投稿2015/08/21 16:38
総合スコア40
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/08/22 06:34
2015/08/22 18:40
2015/08/22 18:41
2015/08/23 19:30
2015/08/24 15:53
2015/08/24 20:47 編集
2015/08/25 01:37 編集
2015/08/25 11:40 編集
0
使い分けというより、やはりvar付きで使うようにするほうが良いです。
スコープの違いがあることは理解されているようなので、それが理由なんですが、たとえば
- グローバルに変数hogeがある
- 関数fの中だけで使う変数hogeを用意する
という場合に、var宣言しないと、関数fが実行されたときにグローバル変数を変更してしまい、予期しない状況を引き起こします。
実際には単にグローバルというだけでなく、var無しだとスコープの外側の変数を参照/変更してしまいます。
さらに理解を深めるために、変数のホスティング(巻き上げ)やスコープ、クロージャーなんかを調べてみると良いと思います。
投稿2015/08/20 00:49
総合スコア36
0
var 付きは局所変数。var 無しは大域変数ですが。
関数の内部で 外部と同じ変数を他の変数として用いる場合にvar をつけます
例えば
g1=20 ;
for( ii=0 ; ii<g1 ; ii++ ){
b1 = func1( ii ) ;
}
function f1( a1 ){
var g1 = 0 ;
for( var ii=a1 ; ii < a12 ; ii++){
g1 += ii 2 ;
}
return g1 ;
}
と、しておくと、関数の内部で関数の外部と同じ名前の変数を他の変数として使えるわけです。
それと、関数の内部の変数を外部に出したくない場合に用います
投稿2015/08/25 04:45
総合スコア30
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/08/20 14:05