Memeriksa apakah kunci ada di objek JavaScript?

2973

Bagaimana cara saya memeriksa apakah ada kunci tertentu dalam objek atau array JavaScript?

Jika kunci tidak ada, dan saya mencoba mengaksesnya, akankah itu kembali palsu? Atau melempar kesalahan?

Adam Ernst
sumber
2
Semuanya (hampir semuanya) dalam JavaScript adalah sebuah Objek atau dapat dicetak sebagai satu. Di sinilah array asosiatif semu lahir persis seperti yang ditunjukkan @PatrickM.
Andrew Larsson
patokan ini jsben.ch/#/WqlIl memberi Anda gambaran umum tentang cara paling umum bagaimana mencapai pemeriksaan ini.
EscapeNetscape
solusi cepat, biasanya saya lakukan property.key = property.key || 'some default value', kalau-kalau saya ingin kunci itu ada dengan beberapa nilai untuk itu
RGLSV

Jawaban:

4121

Memeriksa ketidaktentuan bukan cara yang akurat untuk menguji apakah kunci itu ada. Bagaimana jika kuncinya ada tetapi nilainya sebenarnya undefined?

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

Anda sebaiknya menggunakan inoperator:

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

Jika Anda ingin memeriksa apakah kunci tidak ada, ingatlah untuk menggunakan tanda kurung:

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

Atau, jika Anda ingin secara khusus menguji properti dari instance objek (dan bukan properti yang diwarisi), gunakan hasOwnProperty:

obj.hasOwnProperty("key") // true

Untuk kinerja perbandingan antara metode yang in, hasOwnPropertydan kunci adalah undefined, melihat ini patokan

Makan Goral
sumber
83
Memiliki properti dengan nilai undefined yang ditentukan secara manual sama sekali tidak masuk akal. Itu akan benar-benar sebuah oxymoron.
joebert
259
Saya yakin ada kasus penggunaan karena properti sengaja diatur ke tidak terdefinisi.
Ates Goral
168
Kasing penggunaan yang valid: Gecko 1.9.1 [Firefox 3.5] tidak memiliki properti window.onhashchange. Gecko 1.9.2 [Firefox 3.6] mengatur properti ini menjadi tidak terdefinisi (sampai hash berubah). Untuk fitur mendeteksi riwayat hash atau versi browser, kita harus menggunakan window.hasOwnProperty ("onhashchange");
SamGoody
7
Masalah serupa terjadi di PHP di mana null == tidak ada: stackoverflow.com/q/418066/372654 dan sayangnya, null juga ada gunanya.
Halil Özgür
80
@ Joebert Hanya karena ada sesuatu yang tidak masuk akal bukan berarti Anda tidak akan menemukannya dalam kode produksi. Ada banyak perpustakaan yang melakukan hal-hal yang tidak masuk akal.
Crashworks
298

jawaban cepat

Bagaimana cara saya memeriksa apakah ada kunci tertentu dalam objek atau array JavaScript? Jika kunci tidak ada dan saya mencoba mengaksesnya, akankah itu kembali palsu? Atau melempar kesalahan?

Mengakses secara langsung properti yang hilang menggunakan gaya array (asosiatif) atau gaya objek akan menghasilkan konstanta yang tidak terdefinisi .

Lambat dan dapat diandalkan di operator dan hasOwnProperty metode

Seperti yang telah disebutkan orang di sini, Anda dapat memiliki objek dengan properti yang terkait dengan konstanta "tidak terdefinisi".

 var bizzareObj = {valid_key:  undefined};

Dalam hal ini, Anda harus menggunakan hasOwnProperty atau di operator untuk mengetahui apakah kuncinya benar-benar ada. Tapi, berapa harganya?

jadi, saya katakan ...

di operator dan hasOwnProperty adalah "metode" yang menggunakan mekanisme Property Descriptor dalam Javascript (mirip dengan refleksi Java dalam bahasa Java).

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

Tipe Deskriptor Properti digunakan untuk menjelaskan manipulasi dan reifikasi atribut properti yang disebutkan. Nilai dari tipe Deskriptor Properti adalah rekaman yang terdiri dari bidang yang dinamai di mana setiap bidang adalah nama atribut dan nilainya adalah nilai atribut yang sesuai seperti yang ditentukan dalam 8.6.1. Selain itu, bidang apa pun mungkin ada atau tidak ada.

Di sisi lain, memanggil metode objek atau kunci akan menggunakan mekanisme Javascript [[Get]]. Itu jauh lebih cepat!

patokan

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

Membandingkan akses kunci di JS.

Menggunakan dalam operator
var result = "Impression" in array;

Hasilnya adalah

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

Hasilnya adalah

16,021,758 ±0.45% ops/sec     91% slower
Mengakses elemen secara langsung (gaya kurung)
var result = array["Impression"] === undefined

Hasilnya adalah

168,270,439 ±0.13 ops/sec     0.02% slower 
Mengakses elemen secara langsung (gaya objek)
var result = array.Impression  === undefined;

Hasilnya adalah

168,303,172 ±0.20%     fastest

EDIT: Apa alasan untuk memberikan undefinednilai pada properti ?

Pertanyaan itu membingungkan saya. Dalam Javascript, setidaknya ada dua referensi untuk objek yang tidak ada untuk menghindari masalah seperti ini: nulldan undefined.

nulladalah nilai primitif yang menunjukkan tidak adanya nilai objek yang disengaja, atau dalam jangka pendek, kurangnya nilai yang dikonfirmasi . Di sisi lain, undefinedadalah nilai yang tidak diketahui (tidak didefinisikan). Jika ada properti yang akan digunakan kemudian dengan nilai yang tepat, pertimbangkan untuk menggunakan nullreferensi alih-alih undefinedkarena pada saat awal properti tersebut dikonfirmasi tidak memiliki nilai.

Membandingkan:

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

Menasihati

Hindari benda dengan undefinednilai. Periksa secara langsung jika memungkinkan dan gunakan nulluntuk menginisialisasi nilai properti. Jika tidak, gunakan inoperator atau hasOwnProperty()metode yang lambat .

EDIT: 12/04/2018 - JANGAN RELEVAN LAGI

Seperti yang dikomentari orang, mesin Javascript versi modern (dengan pengecualian firefox) telah mengubah pendekatan untuk properti akses. Implementasi saat ini lebih lambat dari yang sebelumnya untuk kasus khusus ini tetapi perbedaan antara kunci akses dan objek diabaikan.

rdllopes
sumber
1
Apakah semua metode ini dapat diterima di semua browser yang umum digunakan, misalnya IE8 +?
Justin
11
+1 untuk pembandingan. Terima kasih, ini persis informasi yang saya harapkan. Argumen yang kuat untuk menulis kode yang tidak pernah menetapkan atau mengharapkan kunci berisi nilai yang tidak ditentukan .
TJ Compton
Saya ingin tahu bagaimana Underscore.js telah () dibandingkan, jadi saya menambahkannya ke jsperf ( versi 11 ). Ternyata itu dalam grup lambat bersama dengan dan hasOwnProperty ().
mpoisot
3
Salah satu alasan saya akan menetapkan terdefinisi dengan nilai hash adalah bahwa saya benar-benar ingin menghapus kunci properti dari hash, tapi delete hash[key]ini jauh lebih lambat dibandingkan hash[key] = undefined . Tentu saja dalam kasus ini tidak masuk akal bagi saya untuk membutuhkan inoperator, tetapi bertindak sebagai contoh berlawanan dengan "kita harus selalu menghindari menetapkan nilai yang tidak terdefinisi".
Alan Tam
1
Seperti yang disebutkan oleh @ HüseyinYağlı, jika Anda memeriksa tautan jsperf , kinerjanya telah berubah secara signifikan di antara berbagai metode untuk sebagian besar peramban sejak jawaban ini ditulis. Firefox adalah salah satu dari sedikit yang masih memiliki keunggulan signifikan menggunakan metode array atau objek, tetapi untuk banyak browser lainnya perbedaannya dapat diabaikan.
kevinmicke
144

Itu akan kembali undefined.

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

undefinedadalah nilai konstan khusus. Jadi Anda bisa mengatakan, misalnya

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

Ini mungkin cara terbaik untuk memeriksa kunci yang hilang. Namun, seperti yang ditunjukkan dalam komentar di bawah ini, secara teori dimungkinkan bahwa Anda ingin memiliki nilai yang sebenarnya undefined. Saya tidak pernah perlu melakukan ini dan tidak bisa memikirkan alasan mengapa saya ingin, tetapi hanya demi kelengkapan, Anda dapat menggunakan inoperator

// this works even if you have {"goodbye": undefined}
if( "goodbye" in aa ) {
    // do something
}
Eli Courtwright
sumber
8
Bagaimana jika kuncinya ada tetapi nilainya sebenarnya tidak terdefinisi?
Ates Goral
13
Anda harus menggunakan === daripada == saat membandingkan dengan undefined, jika tidak, null akan membandingkan sama dengan undefined.
Matthew Crumley
10
Eli jawaban Anda tidak sepenuhnya akurat. Karena bagaimanapun (dan tentu saja ini tidak boleh dilakukan) tidak terdefinisi bukan nilai konstan khusus. Bahkan, itu bukan kata kunci yang dipesan dan Anda dapat menimpanya, katakanlah misalnya, itu var undefined = 42;. Saat menguji alat peraga tidak terdefinisi, Anda harus selalu menggunakan ((typeof variable) === "undefined").
ssice
1
@ssice undefinedbukan properti yang bisa ditulisi menurut spec ecma-international.org/ecma-262/5.1/#sec-15.1.1.3
therealrootuser
1
Dalam versi JavaScript yang lebih lama, 'undefined' dan 'NaN' adalah variabel yang dapat diubah yang dapat didefinisikan ulang atau diberi nilai lain . Ini adalah hal yang buruk. Itu diperbaiki dalam ECMAScript 5.
jkdev
29
"key" in obj

Kemungkinan menguji hanya nilai atribut objek yang sangat berbeda dari kunci array

pengguna2320522
sumber
Kode ini akan memberikan true juga untuk kunci yang didefinisikan pada prototipe Kelas: fungsi A () {}; A.prototype.b = 2; var a = new A (); Maka 'b' dalam a adalah benar. Sementara a.hasOwnProperty ('b') tentu saja salah.
Alexander
24

Tiga cara untuk memeriksa apakah suatu properti hadir dalam objek javascript:

  1. !!obj.theProperty
    Akan mengkonversi nilai menjadi bool. kembali trueuntuk semua kecuali falsenilainya
  2. ' theProperty' in obj
    Akan mengembalikan true jika properti itu ada, tidak peduli nilainya (bahkan kosong)
  3. obj.hasOwnProperty('theProperty')
    Tidak memeriksa rantai prototipe. (karena semua objek memiliki toStringmetode, 1 dan 2 akan mengembalikan true di atasnya, sementara 3 dapat mengembalikan false di atasnya.)

Referensi:

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

Lavi Avigdor
sumber
!! obj.theProperty gagal ketika nilainya tidak terdefinisi. Contoh:var a = {a : undefined, b : null}; !!a.a **will return false**
ARJUN
dari ulasan: !!obj.thePropertybukan solusi untuk memeriksa apakah suatu objek memiliki properti bernama theProperty. Gagal untuk nilai properti falsey undefined, null, numerik 0atau NaN, dan string kosong""
traktor53
15

Jika Anda menggunakan pustaka underscore.js maka operasi objek / array menjadi sederhana.

Dalam kasus Anda _memiliki metode yang dapat digunakan. Contoh:

yourArray = {age: "10"}

_.has(yourArray, "age")

mengembalikan true

Tapi,

_.has(yourArray, "invalidKey")

mengembalikan salah

Vatsal
sumber
15

Menjawab:

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

Penjelasan:

The inOperator akan memeriksa apakah kunci ada di objek. Jika Anda memeriksa apakah nilainya tidak ditentukan:, if (myObj["key"] === 'undefined')Anda bisa mengalami masalah karena kunci mungkin ada di objek Anda dengan undefinednilai.

Karena itu, jauh lebih baik untuk menggunakan inoperator terlebih dahulu dan kemudian membandingkan nilai yang ada di dalam kunci begitu Anda sudah tahu keberadaannya.

Webeng
sumber
12

Inilah fungsi pembantu yang menurut saya cukup berguna

Ini keyExists(key, search)dapat digunakan untuk dengan mudah mencari kunci di dalam objek atau array!

Cukup berikan kunci yang ingin Anda temukan, dan cari objek (objek atau array) yang ingin Anda temukan.

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

Sudah cukup andal dan berfungsi dengan baik lintas-browser.

jaredwilli
sumber
6
Ini agak membingungkan: pertama, ketika mencari Array, metode ini memeriksa nilai , bukan kunci. Kedua, mengapa harus melalui array seperti ini ketika Anda bisa menggunakan metode built-in Array.indexOf? (jika Anda mencari nilai, yaitu)
Nick F
9

vanila js

yourObjName.hasOwnProperty(key) : true ? false;

Jika Anda ingin memeriksa apakah objek memiliki setidaknya satu properti di es2015

Object.keys(yourObjName).length : true ? false
Haji Tarik
sumber
7

Solusi ES6

menggunakan Array#somedan Object.keys. Ini akan mengembalikan true jika kunci yang diberikan ada di objek atau false jika tidak.

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

Contoh satu baris.

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

pengguna yang baik
sumber
1
Ini akan gagal untuk properti objek yang tidak dapat dihitung.
Sid
@ Id Beri aku beberapa contoh.
pengguna yang baik
Ini dia let joshua = {name: 'Joshua', alamat: 'London'}; Object.defineProperty (joshua, 'isMarried', {value: true, enumerable: false}); console.log ('isMarried' di Object.keys (joshua))
Sid
Saya menerapkan solusi Anda pada objek saya. Bukankah seharusnya memberi benar untuk output pertama? console.log (Object.keys (joshua) .some (v => v == 'isMarried')); console.log (joshua.isMarried);
Sid
1
Maaf, tetapi apakah Anda memeriksa output dari pernyataan konsol kedua? Object.defineProperty setara dengan menyetel properti menggunakan notasi titik.
Sid
6

Kita bisa menggunakan - hasOwnProperty.call(obj, key);

Cara underscore.js -

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

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

Cara termudah untuk memeriksa adalah

"key" in object

sebagai contoh:

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

Nilai kembali sebagai true menunjukkan bahwa kunci ada di objek.

shekhardtu
sumber
4

Bagi mereka yang sudah lodashtermasuk dalam proyek mereka:
Ada metode _situs Lodash yang mencoba untuk mendapatkan kunci "dalam":

Mendapat nilai pada path objek. Jika nilai yang diselesaikan tidak terdefinisi, nilai default dikembalikan sebagai gantinya.

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>


Ini akan secara efektif memeriksa apakah kunci itu, seberapa dalam , didefinisikan dan tidak akan menimbulkan kesalahan yang dapat membahayakan aliran program Anda jika kunci itu tidak ditentukan.

vsync
sumber
4

Meskipun ini tidak selalu memeriksa apakah ada kunci, itu memeriksa kebenaran suatu nilai. Yang undefineddan nulljatuh di bawah.

Boolean(obj.foo)

Solusi ini bekerja paling baik untuk saya karena saya menggunakan naskah, dan menggunakan string seperti ini 'foo' in objatau obj.hasOwnProperty('foo') untuk memeriksa apakah ada kunci atau tidak tidak memberi saya intellisense.

realappie
sumber
3

Jika Anda ingin memeriksa kunci apa pun pada kedalaman apa pun pada objek dan memperhitungkan nilai falsey pertimbangkan baris ini untuk fungsi utilitas:

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

Hasil

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

Lihat juga paket NPM ini: https://www.npmjs.com/package/has-deep-value

Alex
sumber
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';
sarea
sumber
3

Di dunia 'array' kita bisa melihat indeks sebagai semacam kunci. Yang mengejutkan, inoperator (yang merupakan pilihan tepat untuk objek) juga bekerja dengan array. Nilai yang dikembalikan untuk kunci tidak ada adalahundefined

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

Kamil Kiełczewski
sumber
2

yourArray.indexOf (yourArrayKeyName)> -1

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

fruit.indexOf('apple') > -1

benar


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

fruit.indexOf('apple1') > -1

Salah

Anupam Maurya
sumber
0

Contoh ini dapat menunjukkan perbedaan antara cara-cara defferent. Semoga ini akan membantu Anda memilih yang tepat untuk kebutuhan Anda:

// 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"]
Alexander
sumber
-1

Solusi luar biasa baru dengan Destrukturisasi JavaScript :

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

Periksa penggunaan Destrukturisasi JavaScript lainnya

NAVIN
sumber