JavaScript nesnesinde bir anahtar olup olmadığını kontrol etmek ister misiniz?


2969

Bir JavaScript nesnesinde veya dizisinde belirli bir anahtarın olup olmadığını nasıl kontrol edebilirim?

Bir anahtar yoksa ve erişmeye çalışırsam, yanlış döndürür mü? Veya bir hata mı atacaksınız?


2
JavaScript'teki her şey (neredeyse her şey) bir Nesnedir veya tek olarak kullanılabilir. Bu, sözde ilişkisel dizilerin @PatrickM'nin işaret ettiği gibi doğduğu yerdir.
Andrew Larsson

bu karşılaştırma ölçütü jsben.ch/#/WqlIl , bu denetimi gerçekleştirmenin en yaygın yolları hakkında size genel bir bakış sunar.
EscapeNetscape

hızlı bir çözüm, genellikle ben property.key = property.key || 'some default value', bu anahtarın bir değer ile var olmasını istiyorum, ben gitmek için gitmek
RGLSV

Yanıtlar:


4117

Tanımsızlığı kontrol etmek, bir anahtarın var olup olmadığını test etmenin doğru bir yolu değildir. Anahtar var, ancak değer aslında ne olacak undefined?

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

Bunun yerine inoperatörü kullanmalısınız :

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

Bir anahtarın bulunup bulunmadığını kontrol etmek istiyorsanız, parantez kullanmayı unutmayın:

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

Veya özellikle nesne örneğinin özelliklerini (devralınan özellikleri değil) test etmek istiyorsanız, şunu kullanın hasOwnProperty:

obj.hasOwnProperty("key") // true

Hangi yöntem arasındaki performans karşılaştırması için in, hasOwnPropertyve anahtar undefined, bunu görmek kriter


83
Manuel olarak tanımlanmış undefined değerine sahip bir özelliğe sahip olmak kesinlikle mantıklı değildir. Gerçekten bir oksimoron olurdu.
joebert

259
Kasıtlı olarak tanımsız olarak ayarlanmış özelliklere sahip olmanın kullanım durumları olduğuna ikna oldum.
Ateş Goral

168
Geçerli kullanım örneği: Gecko 1.9.1 [Firefox 3.5] 'in window.onhashchange özelliği yoktur. Gecko 1.9.2 [Firefox 3.6], bu özellik tanımlanmamış olarak ayarlandı (karma değişene kadar). Karma geçmişini veya tarayıcı sürümünü algılamak için window.hasOwnProperty ("onhashchange") kullanılmalıdır;
SamGoody

7
Benzer bir sorun PHP'de null == varolmayan: stackoverflow.com/q/418066/372654 ve maalesef null'un da bir kullanımı var.
Halil Özgür

80
@joebert Bir şeyin saçmalık olması üretim kodunda karşılaşmayacağınız anlamına gelmez. Saçma şeyler yapan birçok kütüphane var.
Crashworks

298

Hızlı cevap

Bir JavaScript nesnesinde veya dizisinde belirli bir anahtarın olup olmadığını nasıl kontrol edebilirim? Bir anahtar yoksa ve erişmeye çalışırsam yanlış döndürür mü? Veya bir hata mı atacaksınız?

(İlişkisel) dizi stili veya nesne stili kullanılarak doğrudan eksik bir özelliğe erişmek tanımsız bir sabit döndürür .

Yavaş ve güvenilir olarak operatör ve hasOwnProperty yöntemi

Burada daha önce bahsedildiği gibi, "tanımsız" bir sabitle ilişkilendirilmiş bir özelliğe sahip bir nesneniz olabilir.

 var bizzareObj = {valid_key:  undefined};

Bu durumda, kullanmak zorunda kalacak hasOwnProperty veya içinde anahtar gerçekten olup olmadığını bilmek operatörü. Ama, ama ne pahasına?

size söylüyorum ...

içinde operatör ve hasOwnProperty (Java dilinde Java yansıması benzer) JavaScript Mülkiyet Tanımlayıcı mekanizmasını kullanın "yöntemleri" dir.

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

Özellik Tanımlayıcı türü, adlandırılmış özellik niteliklerinin değiştirilmesini ve yeniden birleştirilmesini açıklamak için kullanılır. Özellik Tanımlayıcı türünün değerleri, her alanın adının bir öznitelik adı ve değerinin 8.6.1'de belirtilen karşılık gelen bir öznitelik değeri olduğu adlandırılmış alanlardan oluşan kayıtlardır. Ek olarak, herhangi bir alan mevcut olabilir veya olmayabilir.

Öte yandan, bir nesne yöntemini veya anahtarını çağırmak Javascript [[Get]] mekanizmasını kullanacaktır. Bu çok daha hızlı!

kıyaslama

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

JS'deki anahtar erişimini karşılaştırma.

Kullanılması halinde operatörü
var result = "Impression" in array;

Sonuç şuydu

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

Sonuç şuydu

16,021,758 ±0.45% ops/sec     91% slower
Elemanlara doğrudan erişim (parantez stili)
var result = array["Impression"] === undefined

Sonuç şuydu

168,270,439 ±0.13 ops/sec     0.02% slower 
Öğelere doğrudan erişme (nesne stili)
var result = array.Impression  === undefined;

Sonuç şuydu

168,303,172 ±0.20%     fastest

DÜZENLEME: Bir mülke undefineddeğer atama nedeni nedir ?

Bu soru beni şaşırtıyor. Javascript'te, bu tür problemlerden kaçınmak için eksik nesneler için en az iki referans vardır: nullve undefined.

nullherhangi bir nesne değerinin kasıtlı yokluğunu veya kısa vadede onaylanmış değer eksikliğini temsil eden ilkel değerdir. Öte yandan, undefinedbilinmeyen bir değerdir (tanımlanmamıştır). Daha sonra uygun bir değerle kullanılacak bir özellik varsa , ilk anda özelliğin bir değerinin olmadığı doğrulandığı için nullbaşvuruyu kullanmayı düşünün .undefined

Karşılaştırmak:

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[].

Öğüt vermek

Değerli nesnelerden kaçının undefined. Mümkün olduğunda doğrudan kontrol edin ve nullözellik değerlerini başlatmak için kullanın . Aksi takdirde, yavaş inişleci veya hasOwnProperty()yöntemi kullanın.

DÜZENLEME: 12/04/2018 - HERHANGİ BİR İLGİLİ DEĞİL

İnsanların yorumladığı gibi, Javascript motorlarının modern sürümleri (firefox hariç) erişim özellikleri için yaklaşımı değiştirdi. Mevcut uygulama, bu özel durum için öncekinden daha yavaş olmakla birlikte, erişim anahtarı ve nesne arasındaki fark göz ardı edilebilir.


1
IE8 + gibi yaygın olarak kullanılan tüm tarayıcılarda bu yöntemlerin tümü kabul edilebilir mi?
Justin

11
Kıyaslama için +1. Teşekkür ederim, tam olarak bulmayı umduğum bilgiler bu. Kesinlikle tanımlanmamış değeri içermesi için bir anahtar atamayan veya beklemeyen bir kod yazmak için güçlü bir argüman .
TJ Compton

Underscore.js'ın () karşılaştırmasını merak ettim, bu yüzden jsperf'e ( sürüm 11 ) ekledim . İn ve hasOwnProperty () ile birlikte yavaş grupta olduğu ortaya çıkıyor.
mpoisot

3
Bir karma değere tanımsız ayarlayın olurdu bir nedeni aslında karma gelen bu özellik anahtarını silmek istedim, ama olmasıdır delete hash[key]olduğunu çok daha yavaş hash[key] = undefined . Elbette bu durumda inoperatöre ihtiyaç duymam hiçbir anlam ifade etmiyor , ancak “değeri daima tanımsız olarak ayarlamaktan kaçınmalıyız” ifadesine karşı bir örnek olarak hareket ediyor.
Alan Tam

1
@ HüseyinYağlı'nın belirttiği gibi, jsperf bağlantısını kontrol ederseniz , bu yanıt başlangıçta yazıldığından, çoğu tarayıcı için performans önemli ölçüde değişmiştir. Firefox, dizi veya nesne yöntemlerini kullanarak hala önemli bir avantaja sahip olanlardan biridir, ancak diğer birçok tarayıcı için farklılıklar göz ardı edilebilir.
kevinmicke

144

Geri dönecek undefined.

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

undefinedözel bir sabit değerdir. Yani diyebilirsiniz, örneğin

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

Bu muhtemelen eksik anahtarları kontrol etmenin en iyi yoludur. Bununla birlikte, aşağıdaki bir yorumda belirtildiği gibi, gerçek değerin olmasını istediğiniz teorik olarak mümkündür undefined. Bunu yapmak için hiç ihtiyacım olmadı ve neden istediğimi bir neden düşünemiyorum, ama sadece bütünlük uğruna inoperatörü kullanabilirsiniz.

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

8
Anahtar varsa ancak değer aslında tanımsızsa ne olur?
Ateş Goral

13
Undefined ile karşılaştırırken == yerine === kullanmalısınız, aksi takdirde null undefined ile eşittir.
Matthew Crumley

10
Eli cevabınız tam olarak doğru değil. Her neyse (ve elbette bu asla yapılmamalıdır) tanımsız özel bir sabit değer değildir. Aslında, bu ayrılmış bir anahtar kelime değildir ve üzerine yazabilirsiniz, örneğin diyelim var undefined = 42;. Tanımlanmamış sahne testlerini yaparken daima kullanmalısınız ((typeof variable) === "undefined").
ssice

1
@ssice undefinedyazılabilir özellik spesifikasyonu göre değil ecma-international.org/ecma-262/5.1/#sec-15.1.1.3
therealrootuser

1
JavaScript'in önceki sürümlerinde, 'tanımsız' ve 'NaN' yeniden tanımlanabilen veya başka değerler atanabilen değiştirilebilir değişkenlerdi . Bu kötü bir şeydi. ECMAScript 5'de düzeltildi.
jkdev


29
"key" in obj

Yalnızca dizi anahtarlarından çok farklı nesne özellik değerlerini test ediyor olabilir


Bu kod, Sınıf prototipinde tanımlanan bir anahtar için de geçerlidir: işlev A () {}; A.prototype.b = 2; var a = yeni A (); O zaman a 'b' doğrudur. A.hasOwnProperty ('b') elbette yanlıştır.
Alexander

24

Bir özelliğin javascript nesnesinde olup olmadığını kontrol etmenin üç yolu:

  1. !!obj.theProperty
    Değeri boole dönüştürür. döner truetüm ama için falsedeğer
  2. ' theProperty' in obj
    Değeri ne olursa olsun, mülk mevcutsa true değerini döndürür (boş olsa bile)
  3. obj.hasOwnProperty('theProperty')
    Prototip zincirini kontrol etmez. (tüm nesneler toStringyönteme sahip olduğundan , 1 ve 2 üzerinde true değerini döndürürken, 3 üzerinde false değerini döndürebilir.)

Referans:

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


!! obj.theParty, değer tanımlanmadığında başarısız olur. Örn:var a = {a : undefined, b : null}; !!a.a **will return false**
ARJUN

from review: !!obj.thePropertybir nesnenin adlı özelliğe sahip olup olmadığını kontrol etmek için bir çözüm değildir theProperty. Herhangi bir falsey özellik değeri, undefinednull, sayısal 0veya NaNboş dize için ""
başarısız

15

Underscore.js kütüphanesini kullanıyorsanız, nesne / dizi işlemleri basitleşir.

Sizin durumunuzda _.has yöntemi kullanılabilir. Misal:

yourArray = {age: "10"}

_.has(yourArray, "age")

doğru döndürür

Fakat,

_.has(yourArray, "invalidKey")

yanlış döndürür


15

Cevap:

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

Açıklama:

inAnahtar nesneyi varsa operatör kontrol edecektir. Değerin tanımsız olup olmadığını kontrol ettiyseniz: if (myObj["key"] === 'undefined')Nesnenizde bir anahtarla büyük olasılıkla var olabileceğinden sorunlarla karşılaşabilirsiniz undefined.

Bu nedenle, önce inoperatörü kullanmak ve sonra zaten var olduğunu bildiğinizde anahtarın içindeki değeri karşılaştırmak daha iyi bir uygulamadır .


12

İşte oldukça yararlı bulduğum bir yardımcı fonksiyon

Bu keyExists(key, search), nesneler veya diziler içindeki bir anahtarı kolayca aramak için kullanılabilir!

Sadece bulmak istediğiniz anahtarı iletin ve bulmak istediğiniz nesneyi (nesne veya dizi) arayın.

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

Oldukça güvenilir ve çapraz tarayıcı iyi çalışıyor.


6
Bu biraz karışık görünüyor: ilk olarak, bir Array ararken bu yöntem bir anahtarı değil, bir değeri kontrol ediyor . İkincisi, yerleşik Array.indexOfyöntemi kullanabildiğinizde neden böyle bir diziyi yineliyorsunuz ? (bir değer arıyorsanız, bu)
Nick F

9

vanila js

yourObjName.hasOwnProperty(key) : true ? false;

Nesnenin es2015'te en az bir özelliği olup olmadığını kontrol etmek istiyorsanız

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

7

ES6 çözümü

Array#someve kullanarak Object.keys. Bu dönecektir gerçek verilen anahtar nesne veya mevcutsa FALSE bunları yapmazsa.

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');

Tek satırlık örnek.

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


1
Nesnenin sayılamayan özellikleri başarısız olur.
Sid

@Sid Bana bir örnek ver.
tür kullanıcı

Hadi bakalım. hadi joshua = {isim: 'Joshua', adres: 'Londra'}; Object.defineProperty (joshua, 'isMarried', {value: true, numaralandırılabilir: false}); console.log (Object.keys (joshua) içinde 'isMarried')
Sid

Çözümünüzü nesneme uyguluyorum. İlk çıktı için doğru olmamalı mı? console.log (Object.keys (joshua) .some (v => v == 'evlendi')); console.log (joshua.isMarried);
Sid

1
Üzgünüm ama ikinci konsolun çıktısını kontrol ettiniz mi? Object.defineProperty, özelliği nokta gösterimi kullanarak ayarlamakla eşdeğerdir.
Sid

6

Kullanabiliriz - hasOwnProperty.call(obj, key);

Underscore.js yolu -

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

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

5

Kontrol etmenin en kolay yolu

"key" in object

Örneğin:

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

Değeri true olarak döndürmek , anahtarın nesnede olduğunu gösterir.


4

lodashProjelerine dahil olanlar için : "Derin" anahtarlar almaya çalışan
lodash _.get yöntemi vardır:

Nesnenin yolundaki değeri alır. Çözülen değer tanımsızsa, defaultValue yerine döndürülür.

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>


Bu anahtar, ancak eğer etkili bir şekilde kontrol edecektir derin , tanımlanır ve olmayacak o anahtar tanımlı değilse programın akışını zedeleyebilecek bir hata atmak.


4

Bu bir anahtarın var olup olmadığını mutlaka kontrol etmese de, bir değerin gerçekliğini kontrol eder. Hangi undefinedve nullaltına düşer.

Boolean(obj.foo)

Bu çözüm benim için en iyi şekilde çalışıyor çünkü daktilo yazıyorum ve böyle dizeleri kullanıyorum 'foo' in objya da obj.hasOwnProperty('foo') bir anahtarın var olup olmadığını kontrol etmek bana akıllılık sağlamaz.


3

Bir nesnenin herhangi bir derinliğinde herhangi bir anahtarı kontrol etmek ve falsey değerlerini hesaba katmak istiyorsanız, bir yardımcı işlev için bu satırı göz önünde bulundurun:

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

Sonuçlar

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

Ayrıca şu NPM paketine bakın: 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

'Dizi' dünyasında dizinleri bir tür anahtar olarak görebiliriz. inOperatörü şaşırtan şey (nesne için iyi bir seçimdir) de dizilerle çalışır. Mevcut olmayan anahtar için döndürülen değer: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

doğru


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

fruit.indexOf('apple1') > -1

yanlış


0

Bu örnek, farklı yollar arasındaki farkları gösterebilir. İhtiyaçlarınız için doğru olanı seçmenize yardımcı olacağını umuyoruz:

// 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 ile yeni harika çözüm :

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'nın diğer kullanımını kontrol edin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.