Nesnenin JavaScript'te herhangi bir özelliği olup olmadığını nasıl kontrol edebilirim?


168

Bildirdiğimi varsayarak

var ad = {}; 

Bu nesnenin kullanıcı tanımlı herhangi bir özellik içerip içermeyeceğini nasıl kontrol edebilirim?

Yanıtlar:


86

Nesnenizin özellikleri üzerinde aşağıdaki gibi döngü yapabilirsiniz:

for(var prop in ad) {
    if (ad.hasOwnProperty(prop)) {
        // handle prop as required
    }
}

hasOwnProperty()Nesnenin doğrudan özellik olarak belirtilen özelliğe sahip olup olmadığını ve nesnenin prototip zincirinden miras alınmadığını belirlemek için yöntemi kullanmak önemlidir .

Düzenle

Yorumlardan: Bu kodu bir işleve koyabilir ve yorumun bulunduğu kısma ulaşır ulaşmaz yanlış döndürmesini sağlayabilirsiniz.

Performans testi

Herhangi bir özelliği test ederken Object.Keys vs For..In Testi


2
Merhaba Daniel, aslında bir nesnenin kullanıcı tanımlı properies içerip içermediğini kontrol etmek için bir cihaz arıyorum. Belirli bir özelliğin var olup olmadığını kontrol etmemek.
Ricky

7
@Ricky: Bu kodu bir işleve koyabilir ve yorumun bulunduğu kısma ulaşır ulaşmaz yanlış döndürmesini sağlayabilirsiniz.
Daniel Vassallo

8
Bu günlerde Object.keyskullanımı en kolay olacağını düşünüyorum : var a = [1,2,3];a.something=4;console.log(Object.keys(a))Zaten ECMA 5'in bir parçası olduğundan, güvenle şimşleyebilirsiniz: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
HMR

2
ES5 ile "bu günlerin" yerel nesnelerin numaralandırılamayan kendi özellikleri olabileceğini unutmayın Object.defineProperty(obj, 'foo', {enumerable:false, value:'foo'}).
RobG

2
Bu çözüm, var olan anahtarları kontrol etmenin bir yoludur , ancak doğru, verimli ve en doğru yanıt Object.keys (x) .length kullanılarak aşağıdadır. Kendi işlevini yapmana gerek yok, biri zaten var!
dudewad

199

Object.keysBir nesnedeki anahtarların listesini almak ve uzunluğunu test etmek için yerleşik yöntemi kullanabilirsiniz.

var x = {};
// some code where value of x changes and than you want to check whether it is null or some object with values

if(Object.keys(x).length > 0){
 // Your code here if x has some properties  
}

14
Buradaki doğru cevap bu. Yukarıdaki kabul edilen cevap bir çözümdür ve sadece anahtar sayısını kontrol etmekten daha pahalıdır; bu daha mantıklı .
dudewad

6
( "MyString") Object.keys; istenmeyen anahtarlar da verir. Bu cevap bence eksik.
Mike de Klerk

2
@MikedeKlerk lütfen dikkatle okuyun, Object.keys ("mystring") değil; nesnedeki tüm anahtarların dizisini döndürecek olan Object.keys (objectVariableName). örnek: {'x': 'abc', 'y': 'def'} ['x', 'y'] olacak
Dhaval Chaudhary

3
@DhavalChaudhary Yorumuma verdiğiniz yanıt için teşekkür ederiz. Bu kodu denediğimde var str = "MyString"; Object.keys(str);, konsol her karakter için 0 ile 7 arasında 8 tuş çıkarır. Yoksa cevabı hala anlamıyorum.
Mike de Klerk

6
@MikedeKlerk ama sadece dizeler için değil nesneler için bir çözüm lütfen soruya bakın.
Dhaval Chaudhary

111

Basit bir işlev yapmaya ne dersiniz?

function isEmptyObject(obj) {
  for(var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }
  }
  return true;
}

isEmptyObject({}); // true
isEmptyObject({foo:'bar'});  // false

hasOwnPropertyDoğrudan yöntem çağrısı Object.prototypesadece biraz daha eklemektir emniyet normal kullanarak aşağıdaki hayal, obj.hasOwnProperty(...)çağrıyı:

isEmptyObject({hasOwnProperty:'boom'});  // false

Not: (gelecek için) Yukarıdaki yöntem for...inifadeye dayanır ve bu ifade yalnızca numaralandırılabilir özellikler üzerinde yinelenir , şu anda en yaygın olarak uygulanan ECMAScript Standardında (3. sürüm) programcının numaralandırılamayan özellikler oluşturmak için herhangi bir yolu yoktur .

Ancak bu şimdi değişti ECMAScript 5. Baskı ve numaralandırılamayan, yazılamayan veya silinebilen özellikler oluşturabiliyoruz, bu nedenle yukarıdaki yöntem başarısız olabilir , örneğin:

var obj = {};
Object.defineProperty(obj, 'test', { value: 'testVal', 
  enumerable: false,
  writable: true,
  configurable: true
});
isEmptyObject(obj); // true, wrong!!
obj.hasOwnProperty('test'); // true, the property exist!!

Bu soruna bir ECMAScript 5 çözümü şöyle olacaktır:

function isEmptyObject(obj) {
  return Object.getOwnPropertyNames(obj).length === 0;
}

Object.getOwnPropertyNamesYöntem döner bir Arrayadlarını içeren tüm The kendi özellikleri bulunan nesnenin enumerable veya olmasın , bu yöntem Chrome 5 Beta ve WebKit Gecelik Kurar son zaten var, tarayıcı satıcıları tarafından şimdi uygulanmaktadır.

Object.defineProperty bu tarayıcılarda ve en son Firefox 3.7 Alpha sürümlerinde de mevcuttur.


1
Object.prototype.hasOwnProperty.call (obj, prop) 'a obj.hasOwnProperty (prop)' a göre avantajı nedir?
Casey Chu

3
@Casey, düzenlenmiş, bir nesne hasOwnPropertyözelliği geçersiz kılarsa, işlev çökebilir ... Biraz paranoyak olduğumu biliyorum ... ama bazen kodunuzun hangi ortamda kullanılacağını bilmiyorsunuz, ancak hangi yöntemi kullanmak istediğinizi biliyorsunuz ...
CMS

2
Bu soruyu ve gelecekteki diğer soruları cevapladığınız için +1! :)
Daniel Vassallo

1
Ayrıca Object.prototype, numaralandırılamayan bir özellikle eşleşen bir ada sahip bir mülkünüz varsa , bunun tarafından numaralandırılmadığı IE'de bir hata olduğunu unutmayın for...in. Böylece isEmptyObject({toString:1})başarısız olur. Bu edemez talihsiz nedenlerinden biridir oldukça kullanmak Object, genel amaçlı haritalama olarak.
bobince

1
@ MichaelMartin-Smucker - tuşlar yalnızca numaralandırılabilir kendi özelliklerini döndürür, bu yüzden burada uygun değildir.
RobG

58

İle jQuery kullanabilirsiniz:

$.isEmptyObject(obj); // Returns: Boolean

JQuery 1.4 itibariyle, bu yöntem hem nesnenin kendisinin hem de prototiplerden miras alınan özellikleri (hasOwnProperty kullanmaması nedeniyle) denetler.

İle ECMAScript 5th Edition modern tarayıcılarda (IE9 +, FF4 +, Chrome5'te +, Opera12 +, Safari5 +) Eğer yerleşik kullanabilirsiniz Object.keys yöntemiyle:

var obj = { blah: 1 };
var isEmpty = !Object.keys(obj).length;

Veya sade eski JavaScript:

var isEmpty = function(obj) {
               for(var p in obj){
                  return false;
               }
               return true;
            };



11

Lodash'ı kullanmak istiyorsanız, someyöntemi kullanabilirsiniz .

_.some(obj) // returns true or false

Bu küçük jsbin örneğine bakın


var x = [1,2] // true
djv

@damionjn Kodunuzu örneğe ekledim. Ben dizi yanlış cevap döndüren dizi ile bakın, ama OP başlangıçta bir değişken olarak bir nesne olarak ilan etti, bu yüzden onun bunu kabul etmek için inanıyorum. Yukarıda alt çizgiler isEmpty yöntemini kullanan bir cevap var (lodash aynı yönteme sahiptir). Bu cevabın da aynı sorunu var. İsEmpty'ye boş olmayan bir dizi verirseniz, yanlış sonuç alırsınız.
sfs

Yeterince adil, ancak en iyi uygulamalardan emin olmak için tüm temelleri içeren cevaplar sağlamalıyız. Haklısın, herhangi bir eleştiri yapmadan hemen cevabından geçtim. Sadece geçen herkes için, bu nesnelere adanmış bir yöntem değildir. _.some([1, 2]) // true Önce kontrol ettiğinizden emin olun: stackoverflow.com/a/13356338/1922747
djv

5
for (var hasProperties in ad) break;
if (hasProperties)
    ... // ad has properties

Güvende olmanız ve Nesne prototiplerini kontrol etmeniz gerekiyorsa (bunlar varsayılan olarak orada değil, belirli kütüphaneler tarafından eklenir):

var hasProperties = false;
for (var x in ad) {
    if (ad.hasOwnProperty(x)) {
        hasProperties = true;
        break;
    }
}
if (hasProperties)
    ... // ad has properties

1
çözümünüzde istenmeyen prototip özellikleri için filtreleme yoktur, bu da Prototype.js gibi bir kitaplık veya deneyimsiz bir kullanıcı nesneye ek prototip özellikleri eklediğinde hatalı davranabileceği anlamına gelir. Bu sayfada Daniels çözümüne göz atın.
Joscha

Bir nesnenin prototipini genişletmek için bir kitaplık kullanmanız veya deneyimsiz olmanız gerekmez. Bazı deneyimli programcılar bunu her zaman yapar.
Alsciende

2
for(var memberName in ad)
{
  //Member Name: memberName
  //Member Value: ad[memberName]
}

Üye, üye özelliği, üye değişkeni, her ne demek isterseniz

Yukarıdaki kod, toString de dahil olmak üzere HER ŞEY döndürecektir ... Yalnızca nesnenin prototipinin genişletilip genişletilmediğini görmek istiyorsanız:

var dummyObj = {};  
for(var memberName in ad)
{
  if(typeof(dummyObj[memberName]) == typeof(ad[memberName])) continue; //note A
  //Member Name: memberName
  //Member Value: ad[memberName]

}

Not A: Sahte nesnenin üyesinin test nesnesinin üyesiyle aynı tipte olup olmadığını kontrol ederiz. Uzatılmışsa, dummyobject öğesinin üye türü "tanımsız" olmalıdır


Merhaba, sadece bir nesnenin özellikler içerip içermediğini bilebilir miyim? Teşekkürler
Ricky

çözümünüzde istenmeyen prototip özellikleri için filtreleme yoktur, bu da Prototype.js gibi bir kitaplık veya deneyimsiz bir kullanıcı nesneye ek prototip özellikleri eklediğinde hatalı davranabileceği anlamına gelir.
Joscha

bu sayfada Daniels çözümüne göz atın - daha az hataya eğilimli!
Joscha

2
İlk kod bloğunuz bunu kapsamaz. tanımlanmamış "ad" nesnesine bir değişken eklersem ikinci kod bloğu yanlış davranır. Gerçekten, Daniels cevabını kontrol edin, "hasOwnProperty" adlı yerel bir uygulama kullandığından doğru ve hızlı olan tek şey budur.
Joscha

@Ricky: Bir nesnenin özellik içerip içermediğini kontrol etmek istiyorsanız, cevabımdaki örneği kullanabilirsiniz: stackoverflow.com/questions/2673121/… . Kod yoruma ulaşırsa, nesnenizin doğrudan özellikleri olmaz. Değilse, olur.
Daniel Vassallo

2
var hasAnyProps = false; for (var key in obj) { hasAnyProps = true; break; }
// as of this line hasAnyProps will show Boolean whether or not any iterable props exist

Basit, her tarayıcıda çalışır ve olsa bile teknik olarak öyle nesne üzerinde tüm anahtarlar için bir döngü var DEĞİL hepsini aracılığıyla döngü ... ya orada 0 olduğunu ve döngü çalışmaz ya da bazı vardır ve ilk sonra kırar bir (çünkü kontrol ettiğimiz tek şey HİÇ ... ... neden devam edelim?)


1

Çok geç cevap, ama prototiplerle bu şekilde başa çıkabilirsiniz.

Array.prototype.Any = function(func) {
    return this.some(func || function(x) { return x });
}

Object.prototype.IsAny = function() {
    return Object.keys(this).Any();
}

0

Nesnenin kullanıcı tanımlı olduğundan emin olun, UDO'nun boş olup olmadığını belirlemenin en kolay yolu aşağıdaki kod olacaktır:

isEmpty=
/*b.b Troy III p.a.e*/
function(x,p){for(p in x)return!1;return!0};

Bu yöntem (doğası gereği) tümdengelimsel olsa da - mümkün olan en hızlı ve en hızlı yöntemdir.

a={};
isEmpty(a) >> true

a.b=1
isEmpty(a) >> false 

ps:! tarayıcı tanımlı nesnelerde kullanmayın.


... 0 döndürür; dönüş 1}; aynı olur mu?
commonpike

1
@pike no, return! 1; return! 0 return false ile aynıdır; return true
Christophe

0

Geç cevap, ancak bazı çerçeveler nesneleri numaralandırılabilir olarak ele alır. Bu nedenle, bob.js böyle yapabilir:

var objToTest = {};
var propertyCount = bob.collections.extend(objToTest).count();

0

Aşağıdakileri kullanabilirsiniz:

Çift kişilik patlama emlak arama

var a = !![]; // true
var a = !!null; // false

hasOwnProperty Bu kullandığım bir şey:

var myObject = {
  name: 'John',
  address: null
};
if (myObject.hasOwnProperty('address')) { // true
  // do something if it exists.
}

Bununla birlikte, JavaScript yöntemin adını korumamaya karar verdi, bu yüzden kurcalanabilir.

var myObject = {
  hasOwnProperty: 'I will populate it myself!'
};

myObject içinde pervane

var myObject = {
  name: 'John',
  address: null,
  developer: false
};
'developer' in myObject; // true, remember it's looking for exists, not value.

bir çeşit

if (typeof myObject.name !== 'undefined') {
  // do something
}

Ancak null olup olmadığını denetlemez.

Bence bu en iyi yol.

operatörde

var myObject = {
  name: 'John',
  address: null
};

if('name' in myObject) {
  console.log("Name exists in myObject");
}else{
  console.log("Name does not exist in myObject");
}

sonuç:

MyObject içinde ad var

Burada, in işleci hakkında daha ayrıntılı bilgi veren bir bağlantı bulunmaktadır: Bir nesne özelliğinin var olup olmadığını belirleme


0

ES6 işlevi

/**
 * Returns true if an object is empty.
 * @param  {*} obj the object to test
 * @return {boolean} returns true if object is empty, otherwise returns false
 */
const pureObjectIsEmpty = obj => obj && obj.constructor === Object && Object.keys(obj).length === 0

Örnekler:


let obj = "this is an object with String constructor"
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {}
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = []
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = [{prop:"value"}]
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {prop:"value"}
console.log(pureObjectIsEmpty(obj)) // empty? false

-1

Buna ne dersin?

var obj = {},
var isEmpty = !obj;
var hasContent = !!obj

Bu cevap soruyu cevaplamıyor. OP bir nesnenin kullanıcı tanımlı özellikler içerip içermediğini soruyor - cevabınız nesnenin kendisinin bir Boole yanlış değerine dönüştürülüp dönüştürülmeyeceğini kontrol ediyor.
Jasmonate

... ve daha sonra James'in bu seçeneği cevabına eklediğini fark ettim. Üzgünüm beyler.
Peter Toth
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.