アプリ版:「スタンプのみでお礼する」機能のリリースについて

obj.property のundefined判定

未定義のローカル変数を評価すると、以下の結果になります。

<script type="text/javascript"><!--
var a;
if(a === undefined){ alert('a is undefined!'); } // エラーは発生しない
if(b === undefined){ alert('b is undefined!'); } // 「ReferenceError: b is not defined」のエラーが発生し、if文が評価されない
if('undefined' === typeof b){ alert('b is undefined!'); } // エラーは発生しない
//--></script>

未定義のローカル変数は undefined との比較ではチェックできず、typeof でチェックする必要があることが分かります。
対して、「存在が保証されているオブジェクトの存在しないプロパティ」でチェックすると、以下の結果になります。

<script type="text/javascript"><!--
var obj = { a:'valueA', b:'valueB' };

if(obj.property === undefined){ alert('obj.property is undefined!'); } // エラーは発生しない
if('undefined' === typeof obj.property){ alert('obj.property is undefined!'); } // エラーは発生しない
//--></script>

不思議に思い、ECMA-262 3rd Edition仕様書を読んでみたところ、下記文言が見つかりました。

----------
8.6.2.1 [[Get]] (P)

O の [[Get]] メソッドがプロパティ名 P で呼出されると、次のステップがとられる:
1. O が P という名前のプロパティを持っていなければ、ステップ 4 へ進む。
2. そのプロパティの値を取得する。
3. Result(2) を返す。
4. O の [[Prototype]] が null ならば、undefined を返す。
5. [[Prototype]] の [[Get]] メソッドを、プロパティ名 P で呼び出す。
6. Result(5) を返す。

http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma26 …
----------

この場合、ステップ4の「obj.property が nullなため undefined を返す」という処理が行われた、という解釈で合っているでしょうか?
ほぼ正しいと感じているのですが、「仕様書の中で見るべきところが合っているのか」に自信が持てず、確信に至っていません…。

A 回答 (1件)

よくわかってませんけれど…



>ステップ4の「obj.property が nullなため ~~
objの[[prototype]](obj.propertyではない)がnullなので~~ ではないのでしょうか?

プロパティの有無は、 property in object でも判別可能みたい。

var org = function() { this.a = 'valueA', this.b = 'valueB'; }
org.prototype.c = 'valueC';
var obj2 = new org();

alert(obj2.c); //valueC
alert('c' in obj2); //true
alert('property' in obj2); //false
alert(obj2.hasOwnProperty('c')); //false

この回答への補足

すみません…、自己解決しました。(汗)
「プロパティアクセス演算子」で obj.property の評価についての解説があり、最終的にはやはり [[Get]]メソッド を使用していました。

11.2.1 プロパティアクセス演算子 - 11 式 (Expressions)
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma26 …
8.7.1 GetValue (V) - 8 型 (Types)
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma26 …
8.6.2.1 [[Get]] (P) - 8 型 (Types)
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma26 …

検証頂き、ありがとうございました。

補足日時:2010/06/18 20:09
    • good
    • 0
この回答へのお礼

改めて読み直して、頭を抱えました…。
「obj.prototype がnullならば、undefined を返す」と書きたかったはずなのにw

fujillinさんが回答された内容は、私の理解と一致しています。
とりあえず、「問題ない」ってことなのかな?

しばらく待って、新しい回答がつかなければ締め切りたいと思います。
ありがとうございます。

> プロパティの有無は、 property in object でも判別可能みたい。
babu_babooさんが同じような回答をされていましたね。

hasOwnProperty() は存在しないプロパティを評価したら、false を返し、
in演算子は存在しないプロパティを評価したら、false を返す、ということは分かりました。
(in演算子はちょっと分かりづらいですが、最終的には [[HasProperty]]メソッドを呼び出して、true, false を返しています。)

hasOwnProperty - MDC
https://developer.mozilla.org/ja/Core_JavaScript …
11.8.7 in 演算子 (The in operat - 11 式 (Expressions)
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma26 …
8.7.1 GetValue (V) - 8 型 (Types)
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma26 …
8.6.2.4 [[HasProperty]] (P) - 8 型 (Types)
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma26 …

今回、私が疑問に感じたのは「obj.property を評価するときに、なぜ "ReferenceError: obj.property is not defined" にならないのか?」というものです。
未定義のローカル変数では ReferenceError が返るので、直感的に「未定義のプロパティ参照も ReferenceError になるはずだ」と思ってしまったんです。
だから、「プロパティ評価は、typeof演算子ないしhasOwnProperty() メソッドを使用した方が無難」と今までは考えていたのですが、どうも undefined との比較でも通ってしまうようなので「実際のところはどうすべきなのだろう?」と思いまして。

お礼日時:2010/06/18 18:56

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!