web-dev-qa-db-ja.com

JavaScript-プロパティが定義され、「未定義」または未定義に設定されているかどうかを識別します

次のコードがあるとします。

_function One() {}
One.prototype.x = undefined;

function Two() {}

var o = new One();
var t = new Two();
_

_o.x_と_t.x_はどちらもundefinedと評価されます。 o.hasOwnProperty('x')t.hasOwnProperty('x')はどちらもfalseを返します。 propertyIsEnumerableについても同様です。 2つの質問:

  • O.xが定義され、undefinedに設定されていることを確認する方法はありますか?
  • 何か理由はありますか? (2つは意味的に同等である必要がありますか?)

小さな注意:(oのpropNameに対して)ループを実行すると、文字列の1つとして 'x'が生成されますが、tで実行すると、生成されません-したがって、IS違いがあります内部的に表現されている(少なくともChromeでは)。

37
Claudiu

あなたの方法よりも少し簡単な方法は、 Javascript in operator を使用することです

alert('x' in o); // true
alert('x' in t); // false
66
Greg

object.hasOwnProperty(name)は、同じオブジェクト内にあるオブジェクトに対してのみtrueを返し、プロトタイプのプロパティを含むその他すべてに対してfalseを返します。

function x() {
  this.another=undefined;
};

x.prototype.something=1;
x.prototype.nothing=undefined;
y = new x;

y.hasOwnProperty("something"); //false
y.hasOwnProperty("nothing"); //false
y.hasOwnProperty("another"); //true

"someting" in y; //true
"another" in y; //true

さらに、プロパティを削除する唯一の方法は、削除を使用することです。 undefinedに設定しても、削除されません。

roborg のようにinを使用するのが適切な方法です。

更新:undefinedはプリミティブ値です ECMAScript言語仕様 セクション4.3.2および4.3.9を参照してください。

8
some

Ach、アンチパターンスレッド用のスレッド。

undefinedはキーワードではありません。

書き込みvar foo = undefined;を割り当てると、定義していないシンボルundefinedの値が割り当てられるため、取得する値は"undefined"になります。 UnDeFiNeDまたはNotFineAtAllまたは_qwertyuiopを割り当てた場合も、まったく同じ結果になります。

なぜこんなにひどいのですか?何が起こっているのかを誤って理解することにつながるという事実とは別に、ライブラリをロードしたり、var undefined = true;を書いた開発者を雇ったりするとどうなるでしょうか。

4
annakata

このようなもの?

function isDefined(var){
   return (typeof(window[var]) == 'undefined') ? false : true;
}

または..

function isDefined(var){
   return (window.var === undefined) ? false : true;
}
1
adam

いいえ。undefinedに等しい変数は「定義済み」として認識されるべきではないと思います。

直接undefinedに設定するのは、それを削除するのが面倒な方法です-deleteキーワードを使用するのと同じです。これは、ガベージコレクションが変数/プロパティに影響を与えていないことを意味します。


[[〜#〜]編集[〜#〜]]

hasOwnPropertypropertyIsEnumerableに関するコメントについては、プロトタイプメソッド/プロパティはオブジェクト自体でも列挙可能でもありません。

Object.prototype.foo = 'something';

var o = {bar: 'anything'};
o.hasOwnProperty('foo');  //=> false
o.hasOwnProperty('bar');  //=> true

Object.prototype.hasOwnProperty('foo');  //=> true
1

これを行う1つの方法は次のとおりです。

var definedProperties = [];
for (var prop in o) definedProperties.Push(prop);

if (o.x === undefined && contains(prop, 'x')) {
    //x is defined, but set to undefined
}

ここで、containsは、配列の要素が'x'。これが唯一の方法ですか?

0
Claudiu

あなたはOne.xに時計を置くことを試みることができますが、それはそれが未定義になるときだけあなたに言うでしょう。

0
nickf