arrays 連想配列 indexof - JavaScriptオブジェクトにキーが存在するかどうかを確認しますか?





9 Answers

素早い回答

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

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

遅い信頼性のある演算子とhasOwnPropertyメソッド

既にここで言及しているように、プロパティは "未定義"定数に関連付けられたオブジェクトを持つことができます。

 var bizzareObj = {valid_key:  undefined};

その場合、キーが本当に存在するかどうかを知るためには、 hasOwnPropertyまたはoperatorを使用する必要があります。 しかし、しかし、 どのような価格で?

そう、私はあなたに言う...

in演算子とhasOwnPropertyはJavascriptでProperty Descriptorメカニズムを使用する "メソッド"です(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

オペレータでの使用
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つの参照があります: nullundefined

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

比較:

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の例外を含む)はアクセスプロパティのアプローチを変更しました。 現在の実装は、この特定のケースでは前の実装よりも遅いですが、アクセスキーとオブジェクトの違いは無視できます。

存在チェック json プロパティ

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

キーが存在せず、そのキーにアクセスしようとすると、それはfalseを返しますか? あるいはエラーを投げる?







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

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

参照:

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




回答:

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

説明:

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

そのため、最初にin演算子を使用してinすでに存在することがわかってからキーの内部にある値を比較する方がはるかに優れています。




バニラジュース

yourObjName.hasOwnProperty(key) : true ? false;

es2015にオブジェクトが少なくとも1つのプロパティを持っているかどうかを確認したい場合

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



- hasOwnProperty.call(obj, key);を使うことができます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);
};



彼らのプロジェクトに含まれている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>

これは、そのキーが深いところで定義されているかどうかを効果的にチェックし、そのキーが定義されていない場合、プログラムの流れを損なう可能性のあるエラーをスローしません。




これらの例は、異なる方法の違いを示すことができます。 それがあなたのニーズに合ったものを選ぶのを助けてくれることを願っています:

// 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"]



オブジェクトの任意の深さでキーをチェックし、偽の値を考慮する場合は、この行をユーティリティ関数と見なしてください:

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-valuehttps://www.npmjs.com/package/has-deep-value : https://www.npmjs.com/package/has-deep-value




Related