JavaScriptオブジェクトにキーが存在するかどうかを確認していますか?


2970

JavaScriptオブジェクトまたは配列に特定のキーが存在するかどうかを確認するにはどうすればよいですか?

キーが存在しない場合にアクセスしようとすると、falseが返されますか?またはエラーをスローしますか?


2
JavaScriptのすべて(ほとんどすべて)はオブジェクトであるか、1つにキャストできます。これは、@ PatrickMが指摘したように、疑似連想配列が生まれる場所です。
Andrew Larsson、2013年

このベンチマークjsben.ch/#/WqlIlは、このチェックを実行する最も一般的な方法の概要を示します。
EscapeNetscape

簡単な回避策。通常はproperty.key = property.key || 'some default value'、そのキーに何らかの値を付けて存在させたい場合に備えて
RGLSV

回答:


4120

undefined-nessのチェックは、キーが存在するかどうかをテストする正確な方法ではありません。キーは存在するが値が実際にある場合はundefinedどうなりますか?

var obj = { key: undefined };
obj["key"] !== undefined // false, but the key exists!

代わりにin演算子を使用する必要があります:

"key" in obj // true, regardless of the actual value

キーが存在しないかどうかを確認する場合は、かっこを使用してください。

!("key" in obj) // true if "key" doesn't exist in object
!"key" in obj   // ERROR!  Equivalent to "false in obj"

または、特に継承されたプロパティではなく、オブジェクトインスタンスのプロパティをテストする場合は、次を使用しますhasOwnProperty

obj.hasOwnProperty("key") // true

ある方法との性能比較のためにinhasOwnPropertyそしてキーがありundefined、この参照のベンチマークを


83
手動で定義されたundefinedの値を持つプロパティがあることは、まったく意味がありません。本当に騒動になるだろう。
joebert 2009

259
プロパティを意図的にundefinedに設定するユースケースがあると確信しています。
Ates Goral

168
有効な使用例:Gecko 1.9.1 [Firefox 3.5]にはwindow.onhashchangeプロパティがありません。Gecko 1.9.2 [Firefox 3.6]では、このプロパティが未定義に設定されています(ハッシュが変更されるまで)。ハッシュ履歴またはブラウザーのバージョンを検出する機能を使用するには、window.hasOwnProperty( "onhashchange");を使用する必要があります。
SamGoody 2010

7
PHPにも同様の問題があり、null == nonexistent:stackoverflow.com/q/418066/372654となりますが、残念ながらnullもそこで使用されます。
HalilÖzgür12年

80
@joebert何かがナンセンスだからといって、プロダクションコードで遭遇しないという意味ではありません。無意味なことをするライブラリはたくさんあります。
Crashworks、2014年

298

素早い回答

JavaScriptオブジェクトまたは配列に特定のキーが存在するかどうかを確認するにはどうすればよいですか?キーが存在せず、アクセスしようとすると、falseが返されますか?またはエラーをスローしますか?

(連想)配列スタイルまたはオブジェクトスタイルを使用して欠落しているプロパティに直接アクセスすると、未定義の定数が返されます。

遅いと信頼性オペレータとhasOwnPropertyをする方法

既にここで説明したように、「未定義」定数に関連付けられたプロパティを持つオブジェクトを作成できます。

 var bizzareObj = {valid_key:  undefined};

その場合、hasOwnPropertyまたはin演算子を使用して、キーが実際に存在するかどうかを確認する必要があります。しかし、しかし、どのような価格で?

だから、私はあなたに言います...

in演算子とhasOwnPropertyは、Javascriptのプロパティ記述子メカニズムを使用する「メソッド」です(Java言語のJavaリフレクションと同様)。

http://www.ecma-international.org/ecma-262/5.1/#sec-8.10

プロパティ記述子タイプは、名前付きプロパティ属性の操作と具体化を説明するために使用されます。プロパティ記述子タイプの値は、名前付きフィールドで構成されるレコードであり、各フィールドの名前は属性名であり、その値は8.6.1で指定されている対応する属性値です。さらに、任意のフィールドが存在する場合と存在しない場合があります。

一方、オブジェクトのメソッドまたはキーを呼び出すと、Javascript [[Get]]メカニズムが使用されます。それははるかに速いです!

基準

http://jsperf.com/checking-if-a-key-exists-in-a-javascript-array

JSでのキーアクセスの比較

使用中にオペレータ
var result = "Impression" in array;

結果は

12,931,832 ±0.21% ops/sec      92% slower 
hasOwnPropertyの使用
var result = array.hasOwnProperty("Impression")

結果は

16,021,758 ±0.45% ops/sec     91% slower
要素に直接アクセスする(角括弧スタイル)
var result = array["Impression"] === undefined

結果は

168,270,439 ±0.13 ops/sec     0.02% slower 
要素に直接アクセスする(オブジェクトスタイル)
var result = array.Impression  === undefined;

結果は

168,303,172 ±0.20%     fastest

編集:プロパティにundefined値を割り当てる理由は何ですか?

その質問は私を困惑させます。JavaScriptでは、このような問題を回避するために、存在しないオブジェクトには少なくとも2つの参照がnullありundefinedます。

nullオブジェクト値の意図的な欠如、または短期的には、値の確認された欠如を表すプリミティブ値です。一方、undefinedは不明な値です(定義されていません)。後で適切な値で使用されるプロパティがある場合は、最初の瞬間にプロパティに値がないことが確認されるため、null代わりに参照の使用を検討してください。undefined

比較:

var a = {1: null}; 
console.log(a[1] === undefined); // output: false. I know the value at position 1 of a[] is absent and this was by design, i.e.:  the value is defined. 
console.log(a[0] === undefined); // output: true. I cannot say anything about a[0] value. In this case, the key 0 was not in a[].

アドバイスする

undefined値を持つオブジェクトは避けてください。可能な限り直接確認し、nullプロパティ値の初期化に使用します。それ以外の場合は、slow in演算子またはhasOwnProperty()メソッドを使用します。

編集:12/04/2018-これ以上は関係ありません

人々がコメントしたように、JavaScriptエンジンの最新バージョン(Firefoxを除く)は、アクセスプロパティのアプローチを変更しました。この特定のケースでは、現在の実装は以前の実装よりも低速ですが、アクセスキーとオブジェクトの違いは無視できます。


1
これらの方法はすべて、IE8 +などの一般的に使用されているすべてのブラウザーで受け入れられますか?
ジャスティン

11
ベンチマークの場合は+1。ありがとう、これはまさに私が見つけたいと思っていた情報です。キーを割り当てたり、キーにundefinedが含まれることを期待したりしないコードを記述するための強力な引数。
TJコンプトン

Underscore.jsのhas()の比較方法に興味があったので、それをjsperf(バージョン11)に追加しました。inとhasOwnProperty()と共に遅いグループにあることがわかります。
mpoisot 2015年

3
undefinedをハッシュ値に設定する理由の1つは、実際にはそのプロパティキーをハッシュから削除したかったdelete hash[key]、よりもはるかに遅いため hash[key] = undefinedです。もちろん、この場合、in演算子を必要とすることは意味がありませんが、「値を未定義に設定することは常に避ける必要があります」の反例として機能します。
(アラン・タム)

1
@HüseyinYağlıが述べたように、jsperfリンクを確認すると、この回答は最初に作成されたため、ほとんどのブラウザーのさまざまなメソッド間でパフォーマンスが大幅に変化しています。Firefoxは、配列やオブジェクトのメソッドを使用することで大きな利点がある数少ないものの1つですが、他の多くのブラウザでは、その違いはごくわずかです。
kevinmicke

144

戻りundefinedます。

var aa = {hello: "world"};
alert( aa["hello"] );      // popup box with "world"
alert( aa["goodbye"] );    // popup box with "undefined"

undefined特別な定数値です。たとえば、次のように言うことができます

// note the three equal signs so that null won't be equal to undefined
if( aa["goodbye"] === undefined ) {
    // do something
}

これはおそらく、欠落したキーをチェックするための最良の方法です。ただし、以下のコメントで指摘されているように、実際の値をにすることは理論的には可能ですundefined。私はこれを行う必要がなかったので、なぜ私がしたいのかという理由がわからないのですが、完全を期すために、in演算子を使用することができます

// this works even if you have {"goodbye": undefined}
if( "goodbye" in aa ) {
    // do something
}

8
キーは存在するが値が実際には未定義の場合はどうなりますか?
Ates Goral

13
undefinedと比較する場合は、==の代わりに===を使用する必要があります。そうでない場合、nullはundefinedと等しいと比較します。
マシュークルムリー

10
エリあなたの答えは完全に正確ではありません。とにかく(もちろん、これは決して行われるべきではありません)、undefinedは特別な定数値ではありません。実際、これは予約済みのキーワードではなく、上書きすることができますvar undefined = 42;。たとえば、未定義の小道具をテストするときは、常にを使用する必要があります((typeof variable) === "undefined")
ssice


1
以前のバージョンのJavaScriptでは、「undefined」と「NaN」は変更可能な変数で、再定義したり、他の値を割り当てたりすることができました。これは悪いことでした。ECMAScript 5で修正されました
jkdev

32

受け入れ答えはを参照するオブジェクト。キーの代わりに配列in演算子を使用してデータを検索することに注意してください。

("true" in ["true", "false"])
// -> false (Because the keys of the above Array are actually 0 and 1)

配列内の既存の要素をテストするには:アイテムがJavaScript配列内にあるかどうかを確認する最良の方法?


良い点、ありがとうございます。:)
Lucas Sousa

29
"key" in obj

配列キーとは非常に異なるオブジェクト属性値のみをテストしている可能性があります


このコードは、クラスのプロトタイプで定義されているキーにも当てはまります。次に、aの「b」はtrueです。一方、a.hasOwnProperty( 'b')はもちろんfalseです。
アレクサンダー

24

プロパティがJavaScriptオブジェクトに存在するかどうかを確認する3つの方法:

  1. !!obj.theProperty
    値をブール値に変換します。値true以外のすべてを返しfalseます
  2. thePropertyobjの' 'は
    、プロパティが存在する場合、その値に関係なく(空でも)trueを返します。
  3. obj.hasOwnProperty('theProperty')
    プロトタイプチェーンをチェックしません。(すべてのオブジェクトがtoStringメソッドを持っているので、1と2はtrueを返し、3はfalseを返すことができます。)

参照:

http://book.mixu.net/node/ch5.html


値が未定義の場合、!! obj.thePropertyは失敗します。例:var a = {a : undefined, b : null}; !!a.a **will return false**
ARJUN

レビューから:!!obj.thePropertyオブジェクトは名前付きプロパティを持つかどうかを確認するための解決策ではありませんtheProperty。これは、任意のfalseyプロパティ値のために失敗しundefined、ヌル、数値0NaN、空の文字列""
traktor53

15

underscore.jsライブラリを使用している場合は、オブジェクト/配列の操作が簡単になります。

あなたの場合、_。hasメソッドを使用できます。例:

yourArray = {age: "10"}

_.has(yourArray, "age")

trueを返します

だが、

_.has(yourArray, "invalidKey")

falseを返します


15

回答:

if ("key" in myObj)
{
    console.log("key exists!");
}
else
{
    console.log("key doesn't exist!");
}

説明:

inキーがオブジェクトに存在する場合にオペレータがチェックされます。値が未定義であるかどうかを確認した場合:値をif (myObj["key"] === 'undefined')持つキーがオブジェクトに存在する可能性があるため、問題が発生する可能性がありundefinedます。

そのため、最初にin演算子を使用し、既に存在することがわかったら、キーの内部にある値を比較することをお勧めします。


12

これは私がとても便利だと思うヘルパー関数です

これkeyExists(key, search)は、オブジェクトまたは配列内のキーを簡単に検索するために使用できます。

検索したいキーを渡し、検索したいobj(オブジェクトまたは配列)を検索するだけです。

function keyExists(key, search) {
        if (!search || (search.constructor !== Array && search.constructor !== Object)) {
            return false;
        }
        for (var i = 0; i < search.length; i++) {
            if (search[i] === key) {
                return true;
            }
        }
        return key in search;
    }

// How to use it:
// Searching for keys in Arrays
console.log(keyExists('apple', ['apple', 'banana', 'orange'])); // true
console.log(keyExists('fruit', ['apple', 'banana', 'orange'])); // false

// Searching for keys in Objects
console.log(keyExists('age', {'name': 'Bill', 'age': 29 })); // true
console.log(keyExists('title', {'name': 'Jason', 'age': 29 })); // false

それはかなり信頼性が高く、クロスブラウザでうまく動作します。


6
これは少し混乱しているようです。まず、配列を検索するとき、このメソッドはキーではなく値をチェックしています。次に、組み込みArray.indexOfメソッドを使用できるのに、なぜこのような配列を反復処理するのですか?(あなたが値を探しているなら、それはそれです)
Nick F

9

バニラjs

yourObjName.hasOwnProperty(key) : true ? false;

es2015でオブジェクトに少なくとも1つのプロパティがあるかどうかを確認する場合

Object.keys(yourObjName).length : true ? false

7

ES6ソリューション

とを使用Array#someObject.keysます。指定されたキーがオブジェクトに存在する場合はtrueを返し、存在しない場合はfalseを返します

var obj = {foo: 'one', bar: 'two'};
    
function isKeyInObject(obj, key) {
    var res = Object.keys(obj).some(v => v == key);
    console.log(res);
}

isKeyInObject(obj, 'foo');
isKeyInObject(obj, 'something');

1行の例。

console.log(Object.keys({foo: 'one', bar: 'two'}).some(v => v == 'foo'));


1
オブジェクトの非数値プロパティの場合は失敗します。
2017

@Sid例を挙げてください。
優しいユーザー

どうぞ。let joshua = {name: 'Joshua'、address: 'London'}; Object.defineProperty(joshua、 'isMarried'、{value:true、enumerable:false}); console.log(Object.keysの'isMarried'(ジョシュア))
シド

私はあなたのソリューションを私のオブジェクトに適用しています。それは最初の出力に対してtrueを与えるべきではありませんか?console.log(Object.keys(joshua).some(v => v == 'isMarried')); console.log(joshua.isMarried);
2017

1
申し訳ありませんが、2番目のコンソールステートメントの出力を確認しましたか?Object.definePropertyは、ドット表記を使用してプロパティを設定することと同じです。
2017

6

使用できます- hasOwnProperty.call(obj, key);

underscore.js道-

if(_.has(this.options, 'login')){
  //key 'login' exists in this.options 
}

_.has = function(obj, key) {
  return hasOwnProperty.call(obj, key);
};

5

確認する最も簡単な方法は

"key" in object

例えば:

var obj = {
  a: 1,
  b: 2,
}
"a" in obj // true
"c" in obj // false

trueの戻り値は、キーがオブジェクトに存在することを意味します。


4

ているもののためにlodash自分のプロジェクトに含ま:
lodashあり_.getの「深い」キーを取得しようとする方法は:

オブジェクトのパスの値を取得します。解決された値が未定義の場合、代わりにdefaultValueが返されます。

var object = { 'a': [{ 'b': { 'c': 3 } }] };

console.log(
  _.get(object, 'a[0].b.c'),           // => 3
  _.get(object, ['a', '0', 'b', 'c']), // => 3
  _.get(object, 'a.b.c'),              // => undefined 
  _.get(object, 'a.b.c', 'default')    // => 'default'
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


その鍵は、しかし、もしこれが効果的にチェックします深く、定義されておりません。そのキーが定義されていない場合は、プログラムの流れを害する可能性があるエラーをスローします。


4

これは必ずしもキーが存在するかどうかをチェックするわけではありませんが、値の真正性をチェックします。どちらundefinednull該当するか。

Boolean(obj.foo)

私はtypescriptを使用しており、そのような文字列を使用し'foo' in objたりobj.hasOwnProperty('foo') 、キーが存在するかどうかを確認したりするため、このソリューションは私にとって最適です。インテリセンスは提供されません。


3

オブジェクトの任意の深さでキーをチェックし、誤った値を考慮したい場合は、ユーティリティ関数について次の行を検討してください。

var keyExistsOn = (o, k) => k.split(".").reduce((a, c) => a.hasOwnProperty(c) ? a[c] || 1 : false, Object.assign({}, o)) === false ? false : true;

結果

var obj = {
    test: "",
    locals: {
        test: "",
        test2: false,
        test3: NaN,
        test4: 0,
        test5: undefined,
        auth: {
            user: "hw"
        }
    }
}

keyExistsOn(obj, "")
> false
keyExistsOn(obj, "locals.test")
> true
keyExistsOn(obj, "locals.test2")
> true
keyExistsOn(obj, "locals.test3")
> true
keyExistsOn(obj, "locals.test4")
> true
keyExistsOn(obj, "locals.test5")
> true
keyExistsOn(obj, "sdsdf")
false
keyExistsOn(obj, "sdsdf.rtsd")
false
keyExistsOn(obj, "sdsdf.234d")
false
keyExistsOn(obj, "2134.sdsdf.234d")
false
keyExistsOn(obj, "locals")
true
keyExistsOn(obj, "locals.")
false
keyExistsOn(obj, "locals.auth")
true
keyExistsOn(obj, "locals.autht")
false
keyExistsOn(obj, "locals.auth.")
false
keyExistsOn(obj, "locals.auth.user")
true
keyExistsOn(obj, "locals.auth.userr")
false
keyExistsOn(obj, "locals.auth.user.")
false
keyExistsOn(obj, "locals.auth.user")
true

このNPMパッケージも参照してください:https : //www.npmjs.com/package/has-deep-value


3
const object1 = {
  a: 'something',
  b: 'something',
  c: 'something'
};

const key = 's';

// Object.keys(object1) will return array of the object keys ['a', 'b', 'c']

Object.keys(object1).indexOf(key) === -1 ? 'the key is not there' : 'yep the key is exist';

3

「配列」の世界では、インデックスをある種のキーと見なすことができます。in演算子の驚くべきこと(これはオブジェクトに適しています)も配列で機能します。存在しないキーの戻り値はundefined

let arr = ["a","b","c"]; // we have indexes: 0,1,2
delete arr[1];           // set 'empty' at index 1
arr.pop();               // remove last item

console.log(0 in arr,  arr[0]);
console.log(1 in arr,  arr[1]);
console.log(2 in arr,  arr[2]);


2

yourArray.indexOf(yourArrayKeyName)> -1

fruit = ['apple', 'grapes', 'banana']

fruit.indexOf('apple') > -1

本当


fruit = ['apple', 'grapes', 'banana']

fruit.indexOf('apple1') > -1


0

これらの例は、さまざまな方法の違いを示しています。それがあなたのニーズに合ったものを選ぶのに役立つことを願っています:

// Lets create object `a` using create function `A`
function A(){};
A.prototype.onProtDef=2;
A.prototype.onProtUndef=undefined;
var a=new A();
a.ownProp = 3;
a.ownPropUndef = undefined;

// Let's try different methods:

a.onProtDef; // 2
a.onProtUndef; // undefined
a.ownProp; // 3
a.ownPropUndef; // undefined
a.whatEver; // undefined
a.valueOf; // ƒ valueOf() { [native code] }

a.hasOwnProperty('onProtDef'); // false
a.hasOwnProperty('onProtUndef'); // false
a.hasOwnProperty('ownProp'); // true
a.hasOwnProperty('ownPropUndef'); // true
a.hasOwnProperty('whatEver'); // false
a.hasOwnProperty('valueOf'); // false

'onProtDef' in a; // true
'onProtUndef' in a; // true
'ownProp' in a; // true
'ownPropUndef' in a; // true
'whatEver' in a; // false
'valueOf' in a; // true (on the prototype chain - Object.valueOf)

Object.keys(a); // ["ownProp", "ownPropUndef"]

-1

JavaScript Destructuringによる新しい素晴らしいソリューション:

let obj = {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3",
};

let {key1, key2, key3, key4} = obj;

// key1 = "value1"
// key2 = "value2"
// key3 = "value3"
// key4 = undefined

// Can easily use `if` here on key4
if(!key4) { console.log("key not present"); } // Key not present

JavaScript Destructuringの他の使用を確認してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.