Bagaimana cara memeriksa jika sebuah objek memiliki properti tertentu di JavaScript?
Pertimbangkan:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
Adalah bahwa cara terbaik untuk melakukannya?
I'm benar-benar bingung dengan jawaban yang telah diberikan - kebanyakan dari mereka adalah hanya outright yang salah. Tentu saja anda dapat memiliki properti objek yang telah terdefinisi, null, atau nilai-nilai yang palsu. Jadi hanya mengurangi cek properti untuk typeof ini[properti]
atau, bahkan lebih buruk, x.kunci
akan memberikan anda benar-benar hasil yang menyesatkan.
Itu tergantung pada apa yang anda're looking for. Jika anda ingin tahu jika suatu objek secara fisik mengandung (dan itu tidak datang dari suatu tempat di prototipe rantai) kemudian objek.hasOwnProperty
adalah cara untuk pergi. Semua browser modern mendukung itu. (Itu hilang dalam versi Safari - 2.0.1 dan lebih tua tapi orang-orang versi dari browser yang jarang digunakan lagi.)
Jika apa yang anda're tempat yang sempurna untuk jika suatu objek memiliki properti di atasnya yang iterable (ketika anda iterate atas sifat-sifat objek, maka akan muncul) maka lakukan: prop di objek
akan memberikan efek yang anda inginkan.
Sejak menggunakan hasOwnProperty
mungkin apa yang anda inginkan, dan mengingat bahwa anda mungkin ingin mundur, saya hadir untuk anda solusi berikut:
var obj = {
a: undefined,
b: null,
c: false
};
// a, b, c all found
for ( var prop in obj ) {
document.writeln( "Object1: " + prop );
}
function Class(){
this.a = undefined;
this.b = null;
this.c = false;
}
Class.prototype = {
a: undefined,
b: true,
c: true,
d: true,
e: true
};
var obj2 = new Class();
// a, b, c, d, e found
for ( var prop in obj2 ) {
document.writeln( "Object2: " + prop );
}
function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
if ( Object.prototype.hasOwnProperty ) {
var hasOwnProperty = function(obj, prop) {
return obj.hasOwnProperty(prop);
}
}
// a, b, c found in modern browsers
// b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
if ( hasOwnProperty(obj2, prop) ) {
document.writeln( "Object2 w/ hasOwn: " + prop );
}
}
Di atas adalah bekerja, cross-browser, solusi untuk hasOwnProperty
, dengan satu peringatan: tidak dapat untuk membedakan antara kasus-kasus di mana identik properti pada prototipe dan pada contoh ini hanya mengasumsikan bahwa itu's berasal dari prototipe. Anda bisa mengubahnya untuk menjadi lebih longgar atau ketat, berdasarkan pada situasi anda, tapi setidaknya ini harus menjadi lebih bermanfaat.
Dengan Underscore.js
(yang lebih baik) lodash
:
_.has(x, 'key');
Yang menyebut Objek.prototipe.hasOwnProperty
, tetapi (a) yang lebih pendek untuk mengetik, dan (b) menggunakan "yang aman referensi untuk hasOwnProperty
" (yaitu ia bekerja bahkan jika hasOwnProperty
ditimpa).
Secara khusus, lodash mendefinisikan _.memiliki
sebagai:
function has(object, key) {
return object ? hasOwnProperty.call(object, key) : false;
}
// hasOwnProperty = Object.prototype.hasOwnProperty
Catatan: berikut ini yang saat ini sebagian besar usang berkat modus yang ketat, dan hasOwnProperty
. Solusi yang tepat adalah dengan menggunakan modus yang ketat dan untuk memeriksa keberadaan properti menggunakan obj.hasOwnProperty
. Ini jawaban mendahului kedua hal ini, setidaknya seperti yang banyak diterapkan (ya, itu adalah yang lama). Ambil berikut sebagai catatan sejarah.
Ingatlah bahwa undefined
adalah (sayangnya) tidak reserved word dalam JavaScript jika anda tidak menggunakan modus yang ketat. Oleh karena itu, seseorang (orang lain, jelas) bisa memiliki gagasan besar dari penyesuaian itu, melanggar kode anda.
Yang lebih kuat adalah metode oleh karena itu berikut ini:
if (typeof(x.attribute) !== 'undefined')
Di sisi lain, metode ini jauh lebih verbose dan juga lebih lambat. :-/
Alternatif yang umum adalah untuk memastikan bahwa undefined
adalah benar-benar tidak terdefinisi, misalnya dengan menempatkan kode ke dalam sebuah fungsi yang menerima parameter tambahan, yang disebut undefined
, yang tidak lulus nilai. Untuk memastikan bahwa itu tidak melewati nilai, anda hanya bisa menyebutnya diri anda segera, misalnya:
(function (undefined) {
… your code …
if (x.attribute !== undefined)
… mode code …
})();
if (x.key !== undefined)
Armin Ronacher tampaknya sudah mengalahkan saya untuk itu, tetapi:
Object.prototype.hasOwnProperty = function(property) {
return this[property] !== undefined;
};
x = {'key': 1};
if (x.hasOwnProperty('key')) {
alert('have key!');
}
if (!x.hasOwnProperty('bar')) {
alert('no bar!');
}
Lebih aman, tapi lebih lambat solusi, seperti yang ditunjukkan oleh Konrad Rudolph dan Armin Ronacher akan sama:
Object.prototype.hasOwnProperty = function(property) {
return typeof this[property] !== 'undefined';
};
Anda dapat menggunakan di
operator untuk memeriksa jika properti yang ada pada suatu benda:
x = {'key': 1};
alert("key" in x);
Anda juga dapat loop melalui semua sifat-sifat benda dengan menggunakan bagi - dalam
lingkaran, dan kemudian memeriksa untuk properti tertentu:
for (prop in x) {
if (prop == "key") {
//Do something
}
}
Anda harus mempertimbangkan apakah ini objek properti enumerable atau tidak, karena non-enumerable sifat tidak akan muncul dalam bagi-dalam
lingkaran. Juga, jika enumerable properti membayangi non-enumerable properti prototipe, itu tidak akan muncul di Internet Explorer 8 dan sebelumnya.
Jika anda ingin daftar semua instance properties, apakah enumerable atau tidak, anda dapat menggunakan
Object.getOwnPropertyNames(x);
Ini akan mengembalikan sebuah array dari nama-nama dari semua sifat yang ada pada suatu objek.
Akhirnya, anda dapat menggunakan typeof operator untuk secara langsung memeriksa tipe data dari objek properti:
if (typeof x.key == "undefined") {
alert("undefined");
}
Jika properti tidak ada pada objek, ia akan mengembalikan string yang tidak terdefinisi. Yang lain itu akan mengembalikan properti yang tepat jenis. Namun, perhatikan bahwa hal ini tidak selalu cara yang sah untuk memeriksa jika sebuah objek memiliki properti atau tidak, karena anda bisa memiliki properti yang tidak terdefinisi, dalam hal ini, menggunakan typeof x.key
masih akan kembali benar (meskipun tombol masih dalam objek).
Update: Anda dapat memeriksa apakah sebuah properti yang ada dengan membandingkan ke terdefinisi javascript properti
if (x.key === undefined) {
alert("undefined");
}
Ini harus bekerja kecuali kunci yang secara khusus mengatur ke undefined
di x objek
Let's memotong melalui beberapa kebingungan di sini. Pertama, let's menyederhanakan dengan asumsi hasOwnProperty
sudah ada; hal ini berlaku di sebagian besar browser yang ada saat ini di gunakan.
hasOwnProperty
mengembalikan true jika atribut nama yang lulus itu telah ditambahkan ke objek. Hal ini sepenuhnya independen dari nilai sebenarnya ditugaskan untuk itu yang mungkin tepat undefined
.
Oleh karena:
var o = {}
o.x = undefined
var a = o.hasOwnProperty('x') // a is true
var b = o.x === undefined // b is also true
Namun:
var o = {}
var a = o.hasOwnProperty('x') // a is now false
var b = o.x === undefined // b is still true
Masalahnya adalah apa yang terjadi ketika sebuah objek dalam prototipe rantai memiliki atribut dengan nilai yang tidak terdefinisi? hasOwnProperty
akan menjadi false untuk itu, dan akan !== undefined
. Namun, for..in
masih akan daftar di pencacahan.
Intinya adalah tidak ada cross-browser cara (sejak Internet Explorer doesn't mengekspos __prototipe__
) untuk menentukan bahwa suatu pengenal tertentu tidak telah melekat pada suatu objek atau apa pun di prototipe rantai.
Jika anda sedang mencari properti, maka "TIDAK". Yang anda inginkan:
if ('prop' in obj) { }
Secara umum anda harus tidak peduli apakah atau tidak properti berasal dari prototipe atau objek.
Namun, karena anda digunakan 'kunci' dalam contoh kode, itu tampak seperti anda memperlakukan objek sebagai hash, dalam hal jawaban anda masuk akal. Semua hash kunci akan properties pada objek, dan anda menghindari sifat tambahan yang disumbangkan oleh prototipe.
John Resig's jawaban yang sangat komprehensif, tapi saya pikir itu bukan't jelas. Terutama ketika menggunakan ",'prop' di obj".
Untuk pengujian benda-benda sederhana menggunakan:
if (obj[x] !== undefined)
Jika anda don't tahu apa jenis objek itu adalah menggunakan:
if (obj.hasOwnProperty(x))
Semua pilihan lain yang lebih lambat..
Detail
Evaluasi kinerja 100,000,000 siklus di bawah Nodejs dengan 5 pilihan yang disarankan oleh orang lain di sini:
function hasKey1(k,o) { return (x in obj); }
function hasKey2(k,o) { return (obj[x]); }
function hasKey3(k,o) { return (obj[x] !== undefined); }
function hasKey4(k,o) { return (typeof(obj[x]) !== 'undefined'); }
function hasKey5(k,o) { return (obj.hasOwnProperty(x)); }
Evaluasi memberitahu kita bahwa jika kita ingin memeriksa objek's prototipe jaringan serta objek itu sendiri, kita tidak harus menggunakan bentuk umum: jika (X Obj)...
Itu adalah antara 2 sampai 6 kali lebih lambat tergantung pada use case
hasKey1 execution time: 4s 510.427785ms
hasKey2 execution time: 0s 904.374806ms
hasKey3 execution time: 0s 760.336193ms
hasKey4 execution time: 0s 935.19901ms
hasKey5 execution time: 2s 148.189608ms
Intinya, jika anda Obj tidak selalu sederhana objek dan anda ingin menghindari memeriksa objek's prototipe rantai dan untuk memastikan x yang dimiliki oleh Obj langsung, menggunakan 'if (obj.hasOwnProperty(x))...'.
Sebaliknya, bila menggunakan objek sederhana dan tidak khawatir tentang objek's prototipe rantai, menggunakan if (typeof(obj[x]) !== 'undefined')...
adalah yang paling aman dan tercepat.
Jika anda menggunakan objek sederhana sebagai sebuah tabel hash dan tidak pernah melakukan sesuatu yang tak biasa, saya akan menggunakan if (obj[x])...
karena saya menemukan ini jauh lebih mudah dibaca.
Bersenang-senang.
Ya itu :) saya pikir anda juga dapat melakukan Objek.prototipe.hasOwnProperty.panggilan(x, 'kunci')
yang juga harus bekerja jika x
memiliki properti yang disebut hasOwnProperty
:)
Tapi yang menguji sifat sendiri. Jika anda ingin memeriksa jika memiliki properti yang mungkin juga inhered anda dapat menggunakan typeof x.foo != 'undefined'
.
Anda juga dapat menggunakan yang ES6 Mencerminkan
objek:
x = {'key': 1};
Reflect.has( x, 'key'); // returns true
Dokumentasi di MDN untuk Mencerminkan.memiliki
dapat ditemukan di sini.
statis
Mencerminkan.memiliki()
metode ini bekerja seperti operator sebagai fungsi.
OK, sepertinya saya punya jawaban yang tepat kecuali jika anda don't ingin mewarisi sifat-sifat:
if (x.hasOwnProperty('key'))
Berikut ini adalah beberapa pilihan lain untuk memasukkan mewarisi sifat-sifat:
if (x.key) // Quick and dirty, but it does the same thing as below.
if (x.key !== undefined)
Jangan lakukan ini objek.hasOwnProperty(kunci))
, yang benar-benar buruk karena metode ini mungkin akan dibayangi oleh sifat pada objek dalam pertanyaan - pertimbangkan { hasOwnProperty: false }
- atau, objek yang dapat menjadi objek null (Objek.membuat(null))
.
Cara terbaik adalah untuk melakukan Objek.prototipe.hasOwnProperty.panggilan(object key)
atau:
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
/* or */
import has from 'has'; // https://www.npmjs.com/package/has
// ...
console.log(has.call(object, key));
hasOwnProperty "dapat digunakan untuk menentukan apakah sebuah objek memiliki properti yang telah ditentukan sebagai properti langsung dari objek tersebut; tidak seperti di operator, metode ini tidak memeriksa ke objek's prototipe jaringan."
Jadi kemungkinan besar, untuk apa yang tampaknya dengan pertanyaan anda, anda don't ingin menggunakan hasOwnProperty, yang menentukan apakah properti yang ada sebagai yang terpasang langsung ke objek itu sendiri,.
Jika anda ingin menentukan apakah properti yang ada di prototipe rantai utama anda ingin gunakan, seperti:
if( prop in object ){ // do something }
Saya harap ini membantu.
Lain relatif sederhana cara menggunakan Objek.tombol
. Hal ini mengembalikan sebuah hotel
yang berarti anda mendapatkan semua fitur dari sebuah array.
var noInfo = {};
var info = {something: 'data'};
Object.keys(noInfo).length //returns 0 or false
Object.keys(info).length //returns 1 or true
Meskipun kita berada di dunia dengan dukungan browser. Karena pertanyaan ini begitu lama saya pikir saya'd tambahkan ini: Ini adalah aman untuk digunakan sebagai JS v1.8.5
Dengan risiko besar downvoting, berikut adalah pilihan lain untuk kasus tertentu. :)
Jika anda ingin menguji untuk anggota pada objek dan ingin tahu apakah itu telah diatur ke sesuatu yang lain dari:
kemudian anda dapat menggunakan:
var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
// member is set, do something
}
Anda dapat menggunakan pendekatan berikut-
var obj = {a:1}
console.log('a' in obj) //1
console.log(obj.hasOwnProperty('a')) //2
console.log(Boolean(obj.a)) //3
Perbedaan antara pendekatan-pendekatan berikut adalah sebagai berikut-
var obj = {
a:2,
__proto__ :{b:2}
}
console.log('b' in obj)
console.log(Boolean(obj.b))
var obj = {
a:2,
__proto__ :{b:2}
}
console.log(obj.hasOwnProperty('b'))
var obj = {
b : undefined
}
console.log(Boolean(obj.b))
console.log('b' in obj);
Ada metode "hasOwnProperty" yang ada pada objek, tetapi tidak dianjurkan untuk memanggil metode ini secara langsung karena mungkin kadang-kadang objek adalah null atau beberapa properti yang ada pada objek seperti: { hasOwnProperty: false }
Jadi cara yang lebih baik akan sama:
// good
var obj = {"bar": "here bar desc"}
console.log(Object.prototype.hasOwnProperty.call(obj, "bar"));
// best
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
console.log(has.call(obj, "bar"));
ECMA Script 6 solusi dengan mencerminkan. Membuat wrapper seperti:
/**
Gets an argument from array or object.
The possible outcome:
- If the key exists the value is returned.
- If no key exists the default value is returned.
- If no default value is specified an empty string is returned.
@param obj The object or array to be searched.
@param key The name of the property or key.
@param defVal Optional default version of the command-line parameter [default ""]
@return The default value in case of an error else the found parameter.
*/
function getSafeReflectArg( obj, key, defVal) {
"use strict";
var retVal = (typeof defVal === 'undefined' ? "" : defVal);
if ( Reflect.has( obj, key) ) {
return Reflect.get( obj, key);
}
return retVal;
} // getSafeReflectArg