JavaScript'te bir değerin nesne olup olmadığını kontrol edin


1364

JavaScript'te bir değerin Nesne olup olmadığını nasıl kontrol edersiniz?


4
Değişken bir değişkendir. Bir nesneye atıfta bulunabilir. Ayrıca, "nesne" tanımlamak isteyebilirsiniz - cevaplar ve yorumlar gösterildiği gibi, birbiriyle çelişen çeşitli tanımlar vardır (örneğin null, bir nesne olup olmadığı ).

8
OP, IMO @ Daan'ın cevabını en iyi çözüm olduğu için kabul etmeli ve ilk önce görülmesi için diğer cevapların üstünde listelenmelidir. (Aynı zamanda iyi cevapları olan başkalarına da suç yoktur.)
tshirt

2
IMHO gerçekten sizin (bu soruya cevap arayan kişi) bir Nesneyi neye ve niye kontrol ettiğine bağlı. Eğer Diziler (yani ayırt etmek çalışıyorsanız, bu soru farklı cevaplar verir vardır den Nesneler) diğer siz "vektörler" dan skaler değerleri ayırmak için çalışıyorsanız Nesneler ya. Boş (yani ister Ve olan typeof göre, bir nesne) veya (Fonksiyonlar olan nesneler) hariç edilip edilmeyeceği, gerçekten bunu kontrol ediyoruz neden bağlıdır. Bu yüzden çok fazla cevap var ve çoğu, bağlamda, doğrudur.
FrancescoMM

const isEmpty = thing => {typeof thing === "nesne"? ! şey || ! Object.keys (şey) .length:! Şey && şey! == 0};
Mayur S

1
Eğer tam olarak ne demek istediğinizi "bir Obje" diyerek başlayabilmeniz harika olurdu . (Veya açık bir şekilde, aradığınız cevabın bir kısmının "popüler" bir nesnenin "çeşitli anlamlarını çivilemek ve daha sonra aralarında ayrım yapmak olduğunu açıkça söyleyin.) Eksik olan, herkesin birbirinden geçmiş olduğunu söylüyor.
Don Hatch

Yanıtlar:


520

GÜNCELLEME :

Bu cevap eksik ve yanıltıcı sonuçlar veriyor . Örneğin, diğer bazı kenar durumlardan bahsetmemek için JavaScript nulltüründe de kabul edilir object. Aşağıdaki öneriyi izleyin ve diğer "en çok oylanan (ve doğru!) Yanıta" geçin .


Orijinal cevap :

typeof(var)Ve / veya kullanmayı deneyin var instanceof something.

DÜZENLEME: Bu yanıt, değişkenin özelliklerinin nasıl inceleneceği hakkında bir fikir verir, ancak nesneden uzak bir nesne olup olmadığını kontrol etmek için kurşun geçirmez bir tarif değildir (sonuçta hiç tarif yoktur!). İnsanlar herhangi bir araştırma yapmadan buradan kopyalanacak bir şey aramaya eğilimli olduklarından, diğer en güncel (ve doğru!) Cevaba dönmelerini şiddetle tavsiye ederim.


208
typeofbir operatör, bu yüzden gerek yok ().
Yoshi

67
Evet, gerek yok. Sadece bu şekilde tercih ederim.
Michael Krelin - hacker

150
@ MichaelKrelin-hacker: İnsanları karıştırdığı için bu talihsiz bir durum .
RightSaidFred

11
@RightSaidFred, bunun için herhangi bir açıklama yok, ama kesinlikle bu ifadelerde :) ekstra parantez eklemek için eğimli değilim
Hacker - Michael Krelin

117
Bu cevap yanlış. typeofnull için 'object' değerini döndürür; bu bir nesne instanceofdeğildir ve kullanılarak oluşturulan nesneler için çalışmaz Object.create(null).
Nikolai

1633

Eğer typeof yourVariable === 'object'bir nesne veya null ise. Eğer null değerini hariç tutmak istiyorsanız, sadece yapın typeof yourVariable === 'object' && yourVariable !== null.


31
İşlevler de nesnedir ve çekinize dahil edilmelidir.
JS_Riddler

4
Bu durumda daha yourVariable !== nulliyi bir uygulama olur mu?
hippietrail

9
@RightSaidFred o görünüyor typeof null == 'object'sabit olmayacaktır ES6 . Dediler ki:This proposal has been rejected. It was implemented in V8 but it turned out that it broke a lot of existing sites. In the spirit of One JavaScript this is not feasible.
Konstantin Smolyanin

2
@Orion'un basit cevabı dizilerin nesne olarak kabul edilmesidir. Daha ayrıntılı bir cevap için, okumak zorundasınız typeofçünkü çok fazla mantıklı olmayan birkaç özel durum var. Diziler ve diziler olmayan nesneler arasında ayrım yapmaya çalışıyorsanız, kesinlikle kullanmak istemezsiniz typeof.
Matt Fenwick

8
En iyi yolu @Tresdin çalıştırmaktır Object.prototype.toString.call(yourVar)olmak yourVar kontrol etmesi gerekenler. Diziler durumunda, Object.prototype.toString.call([1,2])döndürür[object Array]
Jose Rui Santos

539

Javascript'te "nesne" tanımlayalım . Göre MDN dokümanlar , her bir değer, bir nesne veya ilkel biri geçerlidir:

ilkel, ilkel değer

Nesne olmayan ve yöntemi olmayan veriler. JavaScript'in 5 temel veri türü vardır: dize, sayı, boole, null, tanımsız.

İlkel nedir?

  • 3
  • 'abc'
  • true
  • null
  • undefined

Nesne nedir (ilkel değil)?

  • Object.prototype
  • her şey aşağı indi Object.prototype
    • Function.prototype
      • Object
      • Function
      • function C(){} - kullanıcı tanımlı fonksiyonlar
    • C.prototype- kullanıcı tanımlı bir işlevin prototip özelliği: bu bir prototip değil C
      • new C() - "yeni" - kullanıcı tanımlı bir işlev
    • Math
    • Array.prototype
      • diziler
    • {"a": 1, "b": 2} - değişmez gösterim kullanılarak oluşturulan nesneler
    • new Number(3) - ilkellerin etrafındaki sarmalayıcılar
    • ... başka pek çok şey ...
  • Object.create(null)
  • her şey bir Object.create(null)

Bir değerin nesne olup olmadığını kontrol etme

instanceof kendi başına işe yaramaz, çünkü iki vakayı kaçırır:

// oops:  isObject(Object.prototype) -> false
// oops:  isObject(Object.create(null)) -> false
function isObject(val) {
    return val instanceof Object; 
}

typeof x === 'object'yanlış pozitifler ( null) ve yanlış negatifler (işlevler) nedeniyle çalışmaz :

// oops: isObject(Object) -> false
function isObject(val) {
    return (typeof val === 'object');
}

Object.prototype.toString.call işe yaramaz, çünkü tüm ilkellerin yanlış pozitifleri:

> Object.prototype.toString.call(3)
"[object Number]"

> Object.prototype.toString.call(new Number(3))
"[object Number]"

Bu yüzden kullanıyorum:

function isObject(val) {
    if (val === null) { return false;}
    return ( (typeof val === 'function') || (typeof val === 'object') );
}

@ Daan'ın yanıtı da işe yarıyor:

function isObject(obj) {
  return obj === Object(obj);
}

çünkü MDN belgelerine göre :

Nesne yapıcısı, verilen değer için bir nesne sarmalayıcısı oluşturur. Değer null veya undefined ise, boş bir nesne oluşturur ve döndürür, aksi takdirde, verilen değere karşılık gelen türde bir nesne döndürür. Değer zaten bir nesneyse, değeri döndürür.


(Bu% 100 emin değilse) kullanımına işle görünüyor Üçüncü bir yol , bir istisna atar onun argümanı bir nesne değilse:Object.getPrototypeOf

// these 5 examples throw exceptions
Object.getPrototypeOf(null)
Object.getPrototypeOf(undefined)
Object.getPrototypeOf(3)
Object.getPrototypeOf('abc')
Object.getPrototypeOf(true)

// these 5 examples don't throw exceptions
Object.getPrototypeOf(Object)
Object.getPrototypeOf(Object.prototype)
Object.getPrototypeOf(Object.create(null))
Object.getPrototypeOf([])
Object.getPrototypeOf({})

22
obj === Object(obj)truediziler için döner .
Onur Yıldırım

5
var x = []; console.log(x === Object(x)); // return true
Aydınlatıcı

6
@Illuminator diziler vardır benim cevap belirtildiği gibi JavaScript nesneleri.
Matt Fenwick

1
getPrototypeOförneğin, nesneler olan, ancak atılan iptal edilmiş proxy'lerle çalışmaz.
Oriol

2
({}).toString.apply(obj) === '[object Object]'Bu neden diziler ve diziler olmayan nesneler arasında ayrım yapmıyor
MauricioJuanes

295

underscore.js bir şeyin gerçekten bir nesne olup olmadığını öğrenmek için aşağıdaki yöntemi sağlar:

_.isObject = function(obj) {
  return obj === Object(obj);
};

GÜNCELLEME

V8'deki önceki bir hata ve küçük mikro hız optimizasyonu nedeniyle, yöntem underscore.js 1.7.0'dan (Ağustos 2014) beri aşağıdaki gibi görünüyor :

_.isObject = function(obj) {
  var type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};

57
Javascript'te bir dizi de bir nesnedir, bu nedenle çoğu zaman diziyi hariç tutmak istersiniz:return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
Daan

22
neden bir diziyi hariç tuttun? Bunlar tam teşekküllü nesnelerdir.
Nikolai

65
Çünkü çoğu zaman bir {} öğesini bir işlevden girdi olarak [] ile ayırmak istersiniz
Daan

5
@Nickolai ..ve iç içe nesneler arasında yineleme için.
Ricky Boyce

6
Mükemmel cevap. Kulplar nullda. Kabul edilen cevap olmalı.
şifon

180

Object.prototype.toString.call(myVar) geri dönücek:

  • "[object Object]" myVar bir nesne ise
  • "[object Array]" myVar bir dizi ise
  • vb.

Bu ve neden typeof için iyi bir alternatif olduğu hakkında daha fazla bilgi için bu makaleye göz atın .


12
Geçenlerde öğrendim typeof [] === 'object'-> true. Bu yönteme ihtiyacınız var.
Jondlm

3
@Christophe İlkel ve nesneler arasında ayrım yapmaz . Object.prototype.toString.call(3)-> "[object Number]". Object.prototype.toString.call(new Number(3))-> "[object Number]"
Matt Fenwick

3
@MattFenwick Ben OP bu tespit etmeye çalışıyor "nesne" tür olduğunu sanmıyorum
Christophe

3
@Christophe bunu neden düşünüyorsun? IMHO, OP tarafından "nesne" için verilen başka bir tanımın yokluğunda, ECS spesifikasyonu boyunca tutarlı bir şekilde kullanılan tanımla gitmek benim için en mantıklı görünüyor.
Matt Fenwick

getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
Bay Polywhirl

115

Ek işlev çağrısı (hız) olmadan basitçe Nesne veya Diziye karşı kontrol etmek için. As da yayınlanmıştır burada .

isArray ()

isArray = function(a) {
    return (!!a) && (a.constructor === Array);
};
console.log(isArray(        )); // false
console.log(isArray(    null)); // false
console.log(isArray(    true)); // false
console.log(isArray(       1)); // false
console.log(isArray(   'str')); // false
console.log(isArray(      {})); // false
console.log(isArray(new Date)); // false
console.log(isArray(      [])); // true

isObject () - Not: yeni Tarih veya yeni YourCustomObject gibi özel nesneler için yanlış döndürdüğü için yalnızca Nesne değişmezleri için kullanın.

isObject = function(a) {
    return (!!a) && (a.constructor === Object);
};
console.log(isObject(        )); // false
console.log(isObject(    null)); // false
console.log(isObject(    true)); // false
console.log(isObject(       1)); // false
console.log(isObject(   'str')); // false
console.log(isObject(      [])); // false
console.log(isObject(new Date)); // false
console.log(isObject(      {})); // true

isObjectyalnızca nesne değişmezleriyle çalışır. Özel bir tür oluşturursam, türün bir örneğini oluşturur ve test eder, döndürürfalse
WickyNilliams

3
@zupa: ne !! a yapar?

4
@ 3000 kuyusu, eğer (!! a) kısmını dışarıda bırakırsak çöküyor, çünkü null ve undefined hiçbir kurucuya sahip değil. (!! a) onları filtreler. senin sorunun cevabı bu mu?
zupa

2
@zupa @ 3000 Boolean(a)daha uzun, ancak çok daha sezgisel. Sadece kullanmayın new Boolean(a): ( işte bu yüzden )!
JayVee

10
Şaşırmış en iyi cevap şu ana kadar aşağıda. Bu temel olarak soruyu cevaplar - bu JSON'da bir {karakterle başlayan bir şey olarak temsil edilir . Dizi durumunda, IE <9'u desteklemeniz gerekmediği sürece Array.isArray(), bir şeyin dizi olup olmadığını belirlemek için kullanabilirsiniz . Sağladığınız tüm test senaryolarını geçer.
Kip

81

Basitçe severim:

function isObject (item) {
  return (typeof item === "object" && !Array.isArray(item) && item !== null);
}

Öğe bir JS nesnesiyse ve bu bir JS dizisi değilse ve bu null… üçünün de doğru olduğunu kanıtlarsa, geri dönün true. Üç koşuldan herhangi biri başarısız olursa, &&test kısa devre falseyapacak ve geri dönecektir. null(Eğer nasıl kullandığınıza bağlı olarak istenirse testi atlanabilir null).

DOKÜMANLAR:

http://devdocs.io/javascript/operators/typeof

http://devdocs.io/javascript/global_objects/object

http://devdocs.io/javascript/global_objects/array/isarray

http://devdocs.io/javascript/global_objects/null


3
Console.log (isObject (new Date ())) hakkında ne dersiniz? Tarih neden bir nesne, bir dizi olmasın?
schirrmacher

5
@macher Çünkü new Date()bir nesne döndürür. Bir dizi mantıksal bir bakış açısından bir nesne değildir - JavaScript bunları işliyor ve rapor ediyor. Ancak pratikte, onları eşit görmek yararlı değildir, çünkü değildir. Bir nesnenin lengthözniteliği yoktur ve push () gibi bir yöntemi yoktur. Ve bazen, özellikle diğer parametreler hangisinin verildiğine bağlıysa, bir dizi veya nesne arasında bir fark yaratmanız gereken aşırı yüklenmiş parametreler vermek isteyebilirsiniz.
StanE

1
@StanE Diziler kesinlikle nesnelerdir. Emin değilim neden nesneleri olamaz düşünmek lengthgibi mülk ne de yöntemleri push, Object.create(Array.prototype)bu olan bir dizi olmayan nesnenin önemsiz counterexample olduğunu. Dizileri özel yapan şey, özel bir [[DefineOwnProperty]] temel iç yöntemi olan egzotik nesneler olmalarıdır, ancak yine de nesnelerdir.
Oriol

4
@Oriol Ne dizilerin nesne olmadığını yazdım ne de nesnelerin bir lengthözelliğe sahip olamayacağını yazdım (nesne değişmezlerinin lengthvarsayılan olarak hiçbir özniteliği olmadığı anlamına geliyordu ). Dizilerin mantıklı bir bakış açısıyla nesne olmadığını yazdım . Program mantığından bahsediyorum. Bazen bir dizinin "gerçek" bir dizi olup olmadığını ve kesinlikle "gerçek" bir nesne olmadığını kontrol etmek gerekir. Bunun Array.isArray()için. Bir nesneyi veya bir dizi nesneyi kabul eden bir fonksiyonunuz olduğunu düşünün. Özel bir özellik veya yöntem olup olmadığını kontrol etmek kirli bir çözümdür. Yerel yol her zaman daha iyidir.
StanE

2
typeof nullolduğu "object"değil "undefined".
2540625

80

Fonksiyonu ile Array.isArray:

function isObject(o) {
  return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}

İşlevsiz Array.isArray:

Sadece yanlış cevaplar için kaç upvotes şaşırttı 😮
Sadece 1 cevap benim testleri geçti !!! Burada basitleştirilmiş sürümümü oluşturdum:

function isObject(o) {
  return o instanceof Object && o.constructor === Object;
}

Bana gelince, açık ve basit ve sadece çalışıyor! İşte testlerim:

console.log(isObject({}));             // Will return: true
console.log(isObject([]));             // Will return: false
console.log(isObject(null));           // Will return: false
console.log(isObject(/.*/));           // Will return: false
console.log(isObject(function () {})); // Will return: false

BİR DAHA ZAMAN: tüm cevaplar bu testleri geçmez !!! 🙈


Nesnenin belirli bir sınıf örneği olduğunu doğrulamanız gerekirse, yapıcıyı kendi sınıfınızla kontrol etmeniz gerekir, örneğin:

function isDate(o) {
  return o instanceof Object && o.constructor === Date;
}

basit test:

var d = new Date();
console.log(isObject(d)); // Will return: false
console.log(isDate(d));   // Will return: true

Sonuç olarak, katı ve sağlam bir kod olacak!


Eğer gibi işlevler oluşturmak olmayacak isDate, isError, isRegExp, bu genelleştirilmiş fonksiyonlar kullanma seçeneğini düşünebilirsiniz vb:

function isObject(o) {
  return o instanceof Object && typeof o.constructor === 'function';
}

daha önce bahsedilen tüm test senaryoları için düzgün çalışmaz, ancak tüm nesneler (düz veya yapılandırılmış) için yeterince iyidir.


isObjectObject.create(null)iç uygulaması buradaObject.create açıklandığı için çalışmaz, ancak daha karmaşık uygulamalarda kullanabilirsiniz:isObject

function isObject(o, strict = true) {
  if (o === null || o === undefined) {
    return false;
  }
  const instanceOfObject = o instanceof Object;
  const typeOfObject = typeof o === 'object';
  const constructorUndefined = o.constructor === undefined;
  const constructorObject = o.constructor === Object;
  const typeOfConstructorObject = typeof o.constructor === 'function';
  let r;
  if (strict === true) {
    r = (instanceOfObject || typeOfObject) && (constructorUndefined || constructorObject);
  } else {
    r = (constructorUndefined || typeOfConstructorObject);
  }
  return r;
};

Bu uygulamaya dayalı olarak npm v1'de zaten oluşturulmuş bir paket var ! Ve daha önce tarif edilen tüm test senaryolarında işe yarar! 🙂


en iyi cevap! burada
prieston

Bu isObject (myDateObject) için false döndürdüğünden, bu sorunun cevabı değildir. Bir değişkenin nesne olup olmadığını söylemez, yalnızca belirli bir sınıfın nesnesiyse. Buradaki soru, herhangi bir nesne için true döndüren genel bir işlev içindir.
Yetanotherjosh

@Yetanotherjosh Bu gerçekten bir cevaptır answer yanıtta anlatılan durumdan bahsetmiştiniz ve nokta - isDatesağlam kod yazmak içinDateObject için kullanmanız gerekir, aksi takdirde kırılgan isObjectyönteminiz olacaktır .
V. Kovpak

@VladimirKovpak Yorumumda kullanmak Datekötü seçildi çünkü evet, cevap tartışıyor Date. Ancak Date, sonsuz olası sınıflardan sadece bir tanesidir ve mesele başka herhangi bir sınıf için geçerlidir. Örnek: class Foo() { }; var x = new Foo(); isObject(x)döndürür false. OP'nin kullanım durumunun tam olarak ne olduğunu bilmiyorum, ancak olası tüm sınıfları bilmek ve özellikle her birine karşı kontrol etmek mümkün olmayacak senaryoları düşünmek kolaydır .
Yetanotherjosh

@Yetanotherjosh Cevabımı güncelledim. Ve 1 vaka daha ekledi.
V. Kovpak

40

Aman Tanrım! Bunun her zamankinden daha kısa olabileceğini düşünüyorum, şunu görelim:

Kısa ve Son Kod

function isObject(obj)
{
    return obj != null && obj.constructor.name === "Object"
}

console.log(isObject({})) // returns true
console.log(isObject([])) // returns false
console.log(isObject(null)) // returns false

Açıklaması

Dönüş Türleri

tür JavaScript nesneleri (dahil null) döndürür"object"

console.log(typeof null, typeof [], typeof {})

Yapıcılarını kontrol etme

Özelliklerini kontrol constructoretmek isimleriyle birlikte işlev döndürür.

console.log(({}).constructor) // returns a function with name "Object"
console.log(([]).constructor) // returns a function with name "Array"
console.log((null).constructor) //throws an error because null does not actually have a property

Function.name ile tanışın

Function.namebir işlevin salt okunur adını veya "anonymous"kapanışlarını döndürür .

console.log(({}).constructor.name) // returns "Object"
console.log(([]).constructor.name) // returns "Array"
console.log((null).constructor.name) //throws an error because null does not actually have a property

Not: 2018 itibariyle, Function.name IE'de çalışmayabilir https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility


3
Bunu çok beğendim, kısa ve öz. Görebildiğim kadarıyla sadece 1 şeyde başarısız oluyor. obj = ise Object.create(null)ve bunu neden yine de yapardınız ...?
Julian Knight

29

Tamam, orada bkz böylece, aynı zamanda nesne, null, Nesne, Diziler ve hatta tarihi olan ilk JavaScript İşlevleri, sorunuzu yanıtlamadan önce Hadi sana bu kavramı verelim değil bu yüzden typeof obj === 'nesne' gibi basit bir yolu yukarıda belirtilen her şey doğru dönecektir , ancak bir işlev yazarak veya JavaScript çerçevelerini kullanarak kontrol etmenin yolları vardır, Tamam:

Şimdi, gerçek bir nesne olan bu nesneye sahip olduğunuzu düşünün (boş veya işlev veya dizi değil):

var obj = {obj1: 'obj1', obj2: 'obj2'};

Saf JavaScript:

//that's how it gets checked in angular framework
function isObject(obj) {
  return obj !== null && typeof obj === 'object';
}

veya

//make sure the second object is capitalised 
function isObject(obj) {
   return Object.prototype.toString.call(obj) === '[object Object]';
}

veya

function isObject(obj) {
    return obj.constructor.toString().indexOf("Object") > -1;
}

veya

function isObject(obj) {
    return obj instanceof Object;
}

Kodunuzda yukarıdaki gibi bu işlevlerden birini çağırarak kullanabilirsiniz ve nesne ise true değerini döndürür:

isObject(obj);

Bir JavaScript çerçevesi kullanıyorsanız, genellikle bu tür işlevleri sizin için hazırladılar, bunlardan bazıları:

jQuery:

 //It returns 'object' if real Object;
 jQuery.type(obj);

Açısal:

angular.isObject(obj);

Alt Çizgi ve Lodash:

//(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
_.isObject(obj);

Ayrıca bir dizi olmadığını kontrol etmek istersiniz. böylece işlev isObject (obj) {return obj! == null && typeof obj === 'object' &&! Array.isArray (obj); }
Matt Goo

Size katılıyorum, ancak yorumda gördüğünüz gibi, açısalJ'lerde nasıl yapıldığı ve fonksiyonun önündeki yorumda bahsettiğimde, Diziyi Nesne olarak sayıyorlar ... daha fazla bilgi için buraya bakın: dokümanlar .angularjs.org / api / ng / function / angular.isObject
Alireza

24

"Nesnedir" ile ne demek istediğinize bağlıdır. İlkel olmayan her şeyi , yani yeni özellikler ayarlayabileceğiniz şeyleri istiyorsanız, bu hile yapmalıdır:

function isAnyObject(value) {
    return value != null && (typeof value === 'object' || typeof value === 'function');
}

Bu ilkeller dışlar (düz sayılar / NaN/ Infinitydüz dizeleri, semboller, true/ false, undefinedve null) ama her şey (dahil olmak üzere gerçek dönmelidir Number, Booleanve Stringnesneler). JS'nin windowveya "gibi" hangi "ana bilgisayar" nesnelerinin consolebirlikte kullanıldığında geri dönmesi gerektiğini tanımlamadığını unutmayın typeof, bu nedenle bunların böyle bir onayla kapsanması zordur.

Bir şeyin "düz" bir nesne olup olmadığını bilmek istiyorsanız, yani bir değişmez olarak {}veya ile oluşturulmuşsa Object.create(null), bunu yapabilirsiniz:

function isPlainObject(value) {
    if (Object.prototype.toString.call(value) !== '[object Object]') {
        return false;
    } else {
        var prototype = Object.getPrototypeOf(value);
        return prototype === null || prototype === Object.prototype;
    }
}

Edit 2018 : Artık Symbol.toStringTagçıktısının özelleştirilmesine izin verdiğinden Object.prototype.toString.call(...), isPlainObjectyukarıdaki işlev falsebazı durumlarda nesne bir gerçek olarak hayatına başlamış olsa bile geri dönebilir . Tartışmalı olarak, özel bir dize etiketine sahip bir nesne artık tam olarak düz bir nesne değildir, ancak bu, düz bir nesnenin Javascript'te bile ne olduğu tanımını daha da karıştırmıştır.


Neden typeof === 'function' bir nesne olarak kabul edilir? Bir işlev bir nesne değildir, değil mi? "Yeni myFunc ()" bir nesne olacak, evet, ama basit bir işlev?
StanE

Hayır, her işlev, nasıl oluşturulduğundan bağımsız olarak Javascript'teki bir nesnedir. Onlarda özellikler ayarlayabilirsiniz (dondurulmadıkları sürece), bunlar instanceof Object, iki özdeş işlev değişmezi kesinlikle eşit değildir, referansla geçirilir, vb.
Son çocuk

21

Tanrım, diğer cevaplarda çok fazla kafa karışıklığı var.

Kısa cevap

typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)

Bunu test etmek için krom konsolda aşağıdaki ifadeleri çalıştırın.

Dava 1.

var anyVar = {};
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // true

Durum 2.

anyVar = [];
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // false

Durum 3.

anyVar = null;
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array); // false

açıklama

Hadi yıkalım

typeof anyVar == 'object'üç adaydan doğrudur - [], {} and null,

anyVar instanceof Object bu adayları ikiye daraltıyor - [], {}

!(anyVar instanceof Array) sadece biriyle daraltır - {}

Davul ruloları lütfen!

Bununla, Javascript'te Array'ı nasıl kontrol edeceğinizi zaten öğrenmiş olabilirsiniz.


2
Dikkat edilmesi gereken, bu bir işlev falseolduğunda da (istendiği gibi) döner anyVar.
Jamie Birch

18

Bir değerin türünü kontrol etmenin en mantıklı yolu typeofoperatör gibi görünüyor . Tek sorun, korkunç bir şekilde kırılmış olması:

  • Null türüne ait olan "object"için döner null.
  • "function"Nesne türüne ait çağrılabilir nesneler için döner .
  • Standart olmayan, çağrılamaz nesneler için istediği her şeyi (neredeyse) döndürebilir. Örneğin, IE gibi görünüyordu "unknown". Tek yasak sonuç "function"ve ilkel tiplerdir.

typeofsadece nullilkel olmayanlar için güvenilirdir . Dolayısıyla, bir değerin bir nesne olup olmadığını kontrol etmenin bir yolu, döndürülen dizenin typeofbir ilkeye karşılık gelmediğinden ve nesnenin olmadığından emin olmaktır null. Ancak sorun, gelecekteki bir standardın yeni bir ilkel tip sunabilmesi ve kodumuzun bir nesne olduğunu düşünmesidir. Yeni türler sık ​​görünmez, ancak örneğin ECMAScript 6 Sembol türünü tanıttı.

Bu nedenle, bunun yerine typeof, yalnızca değerin bir nesne olup olmadığına bağlı olarak sonucu değişen yaklaşımlar öneririm. Aşağıdakiler bir

Bir değerin Nesne türüne ait olup olmadığını test etmek için kapsamlı yolların kapsamlı ancak kapsamlı olmayan listesi.

  • Object inşaatçı

    ObjectYapıcı bir nesne geçirilen bağımsız değişkeni coerces. Zaten bir nesne ise, aynı nesne döndürülür.

    Bu nedenle, değeri bir nesneye zorlamak ve bu nesneyi orijinal değerle kesinlikle karşılaştırmak için kullanabilirsiniz.

    Aşağıdaki işlev, tanıtılan ECMAScript 3'ü gerektirir ===:

    function isObject(value) { /* Requires ECMAScript 3 or later */
      return Object(value) === value;
    }

    Bu yaklaşımı seviyorum çünkü basit ve kendini tanımlayıcı ve benzer bir kontrol booleans, sayı ve dizgiler için de işe yarayacak. Ancak, küreselleşmenin Objectgölgelenmemesine veya değiştirilmemesine dayandığının farkında olun .

  • Kurucular

    Bir kurucu başlattığınızda, yeni oluşturulan örnekten farklı bir değer döndürebilir. Ancak bir nesne olmadığı sürece bu değer göz ardı edilecektir.

    Aşağıdaki işlev ECMAScript 3'ü gerektirir, bu da yapıcıların nesne olmayanları döndürmesine izin verir. ECMAScript 3'ten önce bir hata attı, ancak o zamanlar tryifadeler yoktu.

    function isObject(value) { /* Requires ECMAScript 3 or later */
      return new function() { return value; }() === value;
    }

    Önceki örnekten biraz daha az basit olsa da, bu herhangi bir küresel mülke dayanmaz ve bu nedenle en güvenli olabilir.

  • this değer

    Eski ECMAScript teknik özellikleri, thisdeğerin bir nesne olmasını gerektiriyordu . ECMAScript 3 tanıtıldı Function.prototype.call, rastgele bir thisdeğere sahip bir işlevi çağırmaya izin verdi ancak bir nesneye zorladı.

    ECMAScript 5, bu davranışı kaldıran katı bir mod başlattı, ancak özensiz modda hala buna güvenebiliriz (ancak tartışmasız olmamalıyız).

    function isObject(value) { /* Requires ECMAScript 3 or later in sloppy mode */
      return function() { return this === value; }.call(value);
    }
  • [[Prototip]]

    Tüm sıradan nesnelerin değeri [[Prototip]] adında bir iç yuvaya sahiptir. Bu değer, değeri diğer hangi nesneden miras aldığını belirler. Değer yalnızca bir nesne veya olabilir null. Bu nedenle, istenen değerden miras alan bir nesne oluşturmayı deneyebilir ve çalışıp çalışmadığını kontrol edebilirsiniz.

    Hem Object.createve Object.getPrototypeOfECMAScript'i 5 gerektirir.

    function isObject(value) { /* Requires ECMAScript 5 or later */
      try {
        Object.create(value);
        return value !== null;
      } catch(err) {
        return false;
      }
    }
    function isObject(value) { /* Requires ECMAScript 5 or later */
      function Constructor() {}
      Constructor.prototype = value;
      return Object.getPrototypeOf(new Constructor()) === value;
    }
  • Bazı yeni ECMAScript 6 yolları

    ECMAScript 6, bir değerin bir nesne olup olmadığını kontrol etmek için bazı yeni dolaylı yollar sunar. Daha önce görülen yaklaşımı, değeri, tryhataları yakalamak için bir ifadenin içine sarılmış bir nesne gerektiren bazı koda iletmek için kullanırlar . Bazı gizli örnekler, yorum yapmaya değmez


Not: Kasıtlı olarak Object.getPrototypeOf(value)(ES5) ve Reflectyöntemler (ES6) gibi bazı yaklaşımları atladım, çünkü kötü şeyler yapabilen temel iç yöntemleri çağırıyorlar, örneğin valuebir proxy ise. Güvenlik nedeniyle, örneklerim sadece valuedoğrudan erişmeden referans veriyor.


2
"Sadece cevabım ve Daan tamamen doğru." ilk iki cümlenize tamamen katılmıyorum .
zzzzBov

1
@zzzzBov Evet, tüm cevaplara baktım ve onlar benimki ve Daan'ın dışında her zaman doğru cevabı vermeyi garanti etmiyorlar. Çoğuna çoğaltılabilir karşı örnekler verebilirim. Diğerleri typeof "işlev" veya "nesne" döndürüp döndürmediğini kontrol etmenizi önerir, ancak açıkladığım gibi, spec bazı nesneler için diğer sonuçlara izin verir. Matt Fenwick'in yanıtı Daan ile aynı doğru cevabı içerir, fakat aynı zamanda yanlış cevapları da içerir.
Oriol

1
Cevabınızın "tamamen doğru" olduğu fikrine katılmıyorum, diğerlerinin "her zaman doğru cevabı döndürmediğinden" emin olarak konumumu hiçbir şekilde yalanlamıyor. Ayrıca, soru hangi girdinin hangi çıktıyı üretmesi gerektiğine dair herhangi bir iddiada bulunmaz.
zzzzBov

1
@zzzzBov Soru, bir şeyin nesne olup olmadığını nasıl kontrol edeceğinizi sorar. ECMAScript bir nesnenin ne olduğunu tanımlar, bu yüzden bu tanımı kullanıyorum. Başka makul bir yorum göremiyorum. Başka şeyler yapan cevaplar (diziler hariç) bazı durumlarda yararlı olabilir, ancak bir şeyin nesne olup olmadığını kontrol etmezler.
Oriol


15

Bunu dene

if (objectName instanceof Object == false) {
  alert('Not an object');
}
else {
  alert('An object');
}

14
Booleları neden kontrol ediyorsun?
jkutianski

5
Bu iki durumu özlüyor: Object.prototype instanceof Object-> yanlış. Object.create(null) instanceof Object-> yanlış.
Matt Fenwick

tarihler ne olacak? new Date() instanceof Object => doğru
mauron85

13

Kontrol için kullanıma hazır fonksiyonlar

function isObject(o) {
  return null != o && 
    typeof o === 'object' && 
    Object.prototype.toString.call(o) === '[object Object]';
}

function isDerivedObject(o) {
  return !isObject(o) && 
    null != o && 
    (typeof o === 'object' || typeof o === 'function') &&
    /^\[object /.test(Object.prototype.toString.call(o));
}

// Loose equality operator (==) is intentionally used to check
// for undefined too

// Also note that, even null is an object, within isDerivedObject
// function we skip that and always return false for null

açıklama

  • JavaScript yılında null, Object, Array, Dateve functionhepsi nesnelerdir. Rağmen, nullbiraz yapmacık. Yani, nullilkini kontrol etmek , boş olmadığını tespit etmek daha iyidir .

  • Bir nesne olan typeof o === 'object'garantileri kontrol etmek o. Bu kontrol olmadan, Object.prototype.toStringanlamsız olurdu, çünkü nesneyi her şey için, hatta undefinedve için döndürecekti null! Örneğin: toString(undefined)döner [object Undefined]!

    Sonra typeof o === 'object'giriş, toString.call (O) kontrol etmek için büyük bir yöntemdir obir amacı, böyle bir türevi amacı Array, Dateya da function.

  • In isDerivedObjectiçin fonksiyonunun, bu denetler obir fonksiyondur. Çünkü bir nesne de işlev görüyor, işte bu yüzden orada. Bunu yapmadıysa, işlev yanlış olarak döner. Örnek: isDerivedObject(function() {})dönecekti false, ancak şimdi dönecek true.

  • Kişi her zaman bir nesnenin tanımını değiştirebilir. Böylece bu fonksiyonlar buna göre değiştirilebilir.


Testler

function isObject(o) {
  return null != o && 
    typeof o === 'object' && 
    Object.prototype.toString.call(o) === '[object Object]';
}

function isDerivedObject(o) {
  return !isObject(o) && 
    null != o && 
    (typeof o === 'object' || typeof o === 'function') &&
    /^\[object /.test(Object.prototype.toString.call(o));
}

// TESTS

// is null an object?

console.log(
  'is null an object?', isObject(null)
);

console.log(
  'is null a derived object?', isDerivedObject(null)
);

// is 1234 an object?

console.log(
  'is 1234 an object?', isObject(1234)
);

console.log(
  'is 1234 a derived object?', isDerivedObject(1234)
);

// is new Number(1234) an object?

console.log(
  'is new Number(1234) an object?', isObject(new Number(1234))
);

console.log(
  'is new Number(1234) a derived object?', isDerivedObject(1234)
);

// is function object an object?

console.log(
  'is (new (function (){})) an object?', 
  isObject((new (function (){})))
);

console.log(
  'is (new (function (){})) a derived object?', 
  isObject((new (function (){})))
);

// is {} an object?

console.log(
  'is {} an object?', isObject({})
);

console.log(
  'is {} a derived object?', isDerivedObject({})
);

// is Array an object?

console.log(
  'is Array an object?',
  isObject([])
)

console.log(
  'is Array a derived object?',
  isDerivedObject([])
)

// is Date an object?

console.log(
  'is Date an object?', isObject(new Date())
);

console.log(
  'is Date a derived object?', isDerivedObject(new Date())
);

// is function an object?

console.log(
  'is function an object?', isObject(function(){})
);

console.log(
  'is function a derived object?', isDerivedObject(function(){})
);


13

Eğer prototypebir objectsadece gelip gelmediğini kontrol etmek istiyorsanız Object. Filtreler dışarı String, Number, Array, Arguments, vb

function isObject (n) {
  return Object.prototype.toString.call(n) === '[object Object]';
}

Veya tek ifadeli ok işlevi olarak (ES6 +)

const isObject = n => Object.prototype.toString.call(n) === '[object Object]'

1
Bu en iyi yoldur, ancak 2. hatta daha da kolaylaştıracaktım:return Object.prototype.toString.call(n) === '[object Object]'
mesqueeb

1
nullÇeki de kaldırabilirsiniz , çünküObject.prototype.toString.call(null) === '[object Null]'
Gust van de Wal

12
var a = [1]
typeof a //"object"
a instanceof Object //true
a instanceof Array //true

var b ={a: 1}
b instanceof Object //true
b instanceof Array //false

var c = null
c instanceof Object //false
c instanceof Array //false

Daha fazla ayrıntı vermem istendi. Değişkenimizin bir nesne olup olmadığını kontrol etmenin en temiz ve anlaşılır yolu typeof myVar. Bu bir türü (örn olan bir dize döndürür "object", "undefined").

Ne yazık ki Array ve null'un da bir türü vardır object. Sadece gerçek nesneleri almak için, miras zincirini instanceofoperatör kullanarak kontrol etmeye ihtiyaç vardır . Null değerini ortadan kaldıracak, ancak Array'ın miras zincirinde Object var.

Yani çözüm:

if (myVar instanceof Object && !(myVar instanceof Array)) {
  // code for objects
}

/./ instanceof Object //true
yckart

11

Biraz geç ... "düz nesneler" için (yani, 'x': 5, 'y': 7} gibi) bu küçük parçacığı var:

function isPlainObject(o) {
   return ((o === null) || Array.isArray(o) || typeof o == 'function') ?
           false
          :(typeof o == 'object');
}

Bir sonraki çıktıyı üretir:

console.debug(isPlainObject(isPlainObject)); //function, false
console.debug(isPlainObject({'x': 6, 'y': 16})); //literal object, true
console.debug(isPlainObject(5)); //number, false
console.debug(isPlainObject(undefined)); //undefined, false
console.debug(isPlainObject(null)); //null, false
console.debug(isPlainObject('a')); //string, false
console.debug(isPlainObject([])); //array?, false
console.debug(isPlainObject(true)); //bool, false
console.debug(isPlainObject(false)); //bool, false

O her zaman benim için çalışır. Yalnızca "o" türü "nesne" ise, ancak null, dizi veya işlev yoksa "true" değerini döndürürse. :)


Önceki yanıtlarda belirtildiği gibi, Date nesnesi durumunda yaklaşımınız başarısız olacaktır.
Grzegorz Pawlik

9

lodash isPlainObject , bu sayfaya gelen birçok kişi olabilir. Bir işlev veya dizi verirken false değerini döndürür.


Mükemmel! _.isObjectHangi nesnenin JS'nin bir nesneyi düşündüğünü biliyordum . Ama genellikle ihtiyacım olan şey, örneğin, bir nesne değişmezi ve bir dizi arasında ayrım _.isPlainObjectyapmaktır.
Kireç

9

Bu çalışacak. Doğru, yanlış veya muhtemelen boş döndüren bir işlevdir.

const isObject = obj => obj && obj.constructor && obj.constructor === Object;

console.log(isObject({})); // true
console.log(isObject([])); // false
console.log(isObject(new Function)); // false
console.log(isObject(new Number(123))); // false
console.log(isObject(null)); // null


2
@SeregPie Gelecekte yanıtlarda kod düzenlemekten kaçınmalısınız. Bu cevap olduğu gibi, test yaparken nullson testin sonucu olarak elde ettim false. Bkz. Kodda ne zaman düzenleme yapmalıyım?
Nick

9

Bu sorunun doğru bir şekilde nasıl ele alınacağı konusunda çok fazla karışıklık göründüğünden, 2 sentimi bırakacağım (bu cevap spec uyumlu ve her koşulda doğru sonuçlar üretiyor):

İlkellerin testi: undefined null boolean string number

function isPrimitive(o){return typeof o!=='object'||null}

Bir nesne ilkel değildir:

function isObject(o){return !isPrimitive(o)}

Veya alternatif olarak:

function isObject(o){return o instanceof Object}
function isPrimitive(o){return !isObject(o)}

Herhangi bir Dizi Testi:

const isArray=(function(){
    const arrayTypes=Object.create(null);
    arrayTypes['Array']=true;
    arrayTypes['Int8Array']=true;
    arrayTypes['Uint8Array']=true;
    arrayTypes['Uint8ClampedArray']=true;
    arrayTypes['Int16Array']=true;
    arrayTypes['Uint16Array']=true;
    arrayTypes['Int32Array']=true;
    arrayTypes['Uint32Array']=true;
    arrayTypes['BigInt64Array']=true;
    arrayTypes['BigUint64Array']=true;
    arrayTypes['Float32Array']=true;
    arrayTypes['Float64Array']=true;
    return function(o){
        if (!o) return false;
        return !isPrimitive(o)&&!!arrayTypes[o.constructor.name];
    }
}());

Nesne hariç olmak üzere test: Date RegExp Boolean Number String Functionherhangi bir Dizi

const isObjectStrict=(function(){
    const nativeTypes=Object.create(null);
    nativeTypes['Date']=true;
    nativeTypes['RegExp']=true;
    nativeTypes['Boolean']=true;
    nativeTypes['Number']=true;
    nativeTypes['String']=true;
    nativeTypes['Function']=true;
    return function(o){
        if (!o) return false;
        return !isPrimitive(o)&&!isArray(o)&&!nativeTypes[o.constructor.name];
    }
}());

8

Her şey başarısız olduğunda, bunu kullanıyorum:

var isObject = function(item) {
   return item.constructor.name === "Object";
}; 

1
Neden dize karşılaştırması, neden basit değil item.constructor === Object?
K3 - rnc

nullbir istisna atarUncaught TypeError: Cannot read property 'constructor' of null(…)
Vitim.us

@rounce Eski IE sürümlerini desteklemeyi hedefliyorum, neden IE'de çalışmıyor? Nedeniyle indexOfveya yüzünden constructor.name?
Jankapunkt

8

Ramda fonksiyonel kütüphane JavaScript türlerini tespit etmek için harika bir işlevi vardır.

Alıntı yapan tam fonksiyon :

function type(val) {
  return val === null      ? 'Null'      :
         val === undefined ? 'Undefined' :
         Object.prototype.toString.call(val).slice(8, -1);
}

Çözümün ne kadar basit ve güzel olduğunu fark ettiğimde gülmek zorunda kaldım.

Ramda belgelerinden örnek kullanım :

R.type({}); //=> "Object"
R.type(1); //=> "Number"
R.type(false); //=> "Boolean"
R.type('s'); //=> "String"
R.type(null); //=> "Null"
R.type([]); //=> "Array"
R.type(/[A-z]/); //=> "RegExp"
R.type(() => {}); //=> "Function"
R.type(undefined); //=> "Undefined"

8

Okuma ve uygulamaların bir sürü denedikten sonra, çok az insan gibi değerleri denetlemek için deneyin fark ettik JSON, Math, document1 adım daha uzun prototip zincirleri ile veya nesneler.

typeofDeğişkenimizi kontrol etmek ve daha sonra kenar durumları kesmek yerine typeof, 'nesne olarak kaydedilen yeni ilkel öğeler veya yerel nesneler eklendiğinde refactor'lardan kaçınmaktan kaçınmanın daha kolay olacağını düşündüm. '.

Sonuçta, typeofoperatör size bir şeyin JavaScript için bir nesne olup olmadığını söyleyecektir , ancak JavaScript'in bir nesne tanımı, gerçek dünyadaki çoğu senaryo için çok geniştir (örn. typeof null === 'object'). Aşağıda, viki denetimi tekrarlayarak değişkenin bir nesne olup olmadığını belirleyen bir işlev vardır :

  1. Bir döngü sürece ait dizgelenmiş versiyonu olarak devam etmesi başlatılır volduğunu '[object Object]'.
    İşlevin sonucunun tam olarak aşağıdaki günlükler gibi olmasını istedim, bu yüzden sonuçta karşılaştığım tek "nesnellik" ölçütleri bu. Başarısız olursa, işlev hemen false değerini döndürür.
  2. vzincirindeki bir sonraki prototip ile değiştirilir v = Object.getPrototypeOf(v), ancak sonradan doğrudan değerlendirilir. Yeni değeri volduğunda null, kök prototipi de dahil olmak üzere ( zincirin içindeki tek prototip çok iyi olabilir) her prototipin while döngüsünde denetimi geçtiği ve true'ya dönebileceğimiz anlamına gelir. Aksi takdirde yeni bir yineleme başlar.

function isObj (v) {
  while (     Object.prototype.toString.call(v) === '[object Object]')
  if    ((v = Object.getPrototypeOf(v))         === null)
  return true
  return false
}

console.log('FALSE:')
console.log('[]                   -> ', isObj([]))
console.log('null                 -> ', isObj(null))
console.log('document             -> ', isObj(document))
console.log('JSON                 -> ', isObj(JSON))
console.log('function             -> ', isObj(function () {}))
console.log('new Date()           -> ', isObj(new Date()))
console.log('RegExp               -> ', isObj(/./))

console.log('TRUE:')
console.log('{}                   -> ', isObj({}))
console.log('new Object()         -> ', isObj(new Object()))
console.log('new Object(null)     -> ', isObj(new Object(null)))
console.log('new Object({})       -> ', isObj(new Object({foo: 'bar'})))
console.log('Object.prototype     -> ', isObj(Object.prototype))
console.log('Object.create(null)  -> ', isObj(Object.create(null)))
console.log('Object.create({})    -> ', isObj(Object.create({foo: 'bar'})))
console.log('deep inheritance     -> ', isObj(Object.create(Object.create({foo: 'bar'}))))


6
if(typeof value === 'object' && value.constructor === Object)
{
    console.log("This is an object");
}

1
Eğer valueolduğu nullbu bir hata atar ...
Gershom

Ve tabii ki falsenesne için olacak Object.assign({}, {constructor: null}).
user4642212

6

Açıkça verilen değerin olup olmadığını kontrol etmek istiyorsanız {}.

function isObject (value) {
 return value && typeof value === 'object' && value.constructor === Object;
}

6
const isObject = function(obj) {
  const type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};

!!objdoğru olup olmadığını kontrol etmek için kestirme obj(filtrelemek null)


6

Bu eski bir soru ama bunu burada bırakmayı düşündüm. Çoğu kişi, değişkenin {}eşleştirilmiş bir anahtar / değer çifti olup olmadığını kontrol eder ve JavaScript'in belirli bir şey için kullandığının alt çizgi yapısını değil, dürüst olmak gerekirse, çoğunlukla JavaScript'teki her şey bir nesnedir. Yani bunu yoldan çekerek. Yaparsan...

let x = function() {}
typeof x === 'function' //true
x === Object(x) // true
x = []
x === Object(x) // true

// also
x = null
typeof null // 'object'

Çoğu zaman istediğimiz şey, bir API'den bir kaynak nesnemiz veya ORM'den döndürülen veritabanı çağrımız olup olmadığını bilmek. Daha sonra bir Arraydeğil null, değil , bir tür olup olmadığını 'function've birObject

// To account also for new Date() as @toddmo pointed out

x instanceof Object && x.constructor === Object

x = 'test' // false
x = 3 // false
x = 45.6 // false
x = undefiend // false
x = 'undefiend' // false
x = null // false
x = function(){} // false
x = [1, 2] // false
x = new Date() // false
x = {} // true

babalık trueiçinnew Date()
toddmo

1
@toddmo bunu gösterdiğin için teşekkürler. Şimdi örnek kod için false döndürürnew Date()
Gilbert

4

Kullanmayı sevdiğim şey bu

function isObject (obj) {
  return typeof(obj) == "object" 
        && !Array.isArray(obj) 
        && obj != null 
        && obj != ""
        && !(obj instanceof String)  }

Ben çoğu durumda bir Tarih onay bir nesne olarak geçmesi gerektiğini düşünüyorum, bu yüzden tarihleri ​​filtreleme yok


4

Ben sadece bu tür bir soru kontrol türü bu tür yapmak için "yeni" bir yol buldum: neden instanceof bazı değişmezleri için yanlış döndürür?

ondan, ben aşağıdaki gibi tür denetimi için bir işlev oluşturdu:

function isVarTypeOf(_var, _type){
    try {
        return _var.constructor === _type;
    } catch(ex) {
        return false;         //fallback for null or undefined
    }
}

o zaman sadece şunları yapabilirsiniz:

console.log(isVarTypeOf('asdf', String));   // returns true
console.log(isVarTypeOf(new String('asdf'), String));   // returns true
console.log(isVarTypeOf(123, String));   // returns false
console.log(isVarTypeOf(123, Number));   // returns true
console.log(isVarTypeOf(new Date(), String));   // returns false
console.log(isVarTypeOf(new Date(), Number));   // returns false
console.log(isVarTypeOf(new Date(), Date));   // returns true
console.log(isVarTypeOf([], Object));   // returns false
console.log(isVarTypeOf([], Array));   // returns true
console.log(isVarTypeOf({}, Object));   // returns true
console.log(isVarTypeOf({}, Array));   // returns false
console.log(isVarTypeOf(null, Object));   // returns false
console.log(isVarTypeOf(undefined, Object));   // returns false
console.log(isVarTypeOf(false, Boolean));   // returns true

Chrome 56, Firefox 52, Microsoft Edge 38, Internet Explorer 11, Opera 43 üzerinde test edilmiştir

edit:
bir değişkenin null veya undefined olup olmadığını da kontrol etmek istiyorsanız, bunun yerine şunu kullanabilirsiniz:

function isVarTypeOf(_var, _type){
    try {
        return _var.constructor === _type;
    } catch(ex) {
        return _var == _type;   //null and undefined are considered the same
        // or you can use === if you want to differentiate them
    }
}

var a = undefined, b = null;
console.log(isVarTypeOf(a, undefined)) // returns true
console.log(isVarTypeOf(b, undefined)) // returns true
console.log(isVarTypeOf(a, null)) // returns true

inanc'ın yorumundan güncelleme: meydan okuma kabul edildi: D

nesneleri karşılaştırmak istediğinizde bu şekilde deneyebilirsiniz:

function isVarTypeOf(_var, _type, looseCompare){
    if (!looseCompare){
        try {
            return _var.constructor === _type;
        } catch(ex){
            return _var == _type;
        }
    } else {
        try{
            switch(_var.constructor){
                case Number:
                case Function:
                case Boolean:
                case Symbol:
                case Date:
                case String:
                case RegExp:
                    // add all standard objects you want to differentiate here
                    return _var.constructor === _type;
                case Error:
                case EvalError:
                case RangeError:
                case ReferenceError:
                case SyntaxError:
                case TypeError:
                case URIError:
                    // all errors are considered the same when compared to generic Error
                    return (_type === Error ? Error : _var.constructor) === _type;
                case Array:
                case Int8Array:
                case Uint8Array:
                case Uint8ClampedArray:
                case Int16Array:
                case Uint16Array:
                case Int32Array:
                case Uint32Array:
                case Float32Array:
                case Float64Array:
                    // all types of array are considered the same when compared to generic Array
                    return (_type === Array ? Array : _var.constructor) === _type;
                case Object:
                default:
                    // the remaining are considered as custom class/object, so treat it as object when compared to generic Object
                    return (_type === Object ? Object : _var.constructor) === _type;
            }
        } catch(ex){
            return _var == _type;   //null and undefined are considered the same
            // or you can use === if you want to differentiate them
        }
    }
}

bu şekilde inanc'ın yorumu gibi yapabilirsiniz:

isVarTypeOf(new (function Foo(){}), Object); // returns false
isVarTypeOf(new (function Foo(){}), Object, true); // returns true

veya

Foo = function(){};
Bar = function(){};
isVarTypeOf(new Foo(), Object);   // returns false
isVarTypeOf(new Foo(), Object, true);   // returns true
isVarTypeOf(new Bar(), Foo, true);   // returns false
isVarTypeOf(new Bar(), Bar, true);   // returns true
isVarTypeOf(new Bar(), Bar);    // returns true

Bu, yeni bir sınıfın nesne olup olmadığını algılayamaz. isVarTypeOf (new (function Foo () {}), Object) // Bu, true yerine false değerini döndürür. Doğru kontrol için aşağıdaki cevabıma bakın.
İnanç Gümüş

Ancak, instanceofnesneleri kontrol etmek için kullanabilirsiniz . Yine de, bu tam bir bilim değil.
İnanç Gümüş

@inanc, iyi, çünkü new Foo()bir Foonesneyi new String()döndürür, bir Stringnesneyi new Date()döndürür veya bir Datenesneyi döndürür , Foo = function(){}; isVarTypeOf(new Foo(), Foo);ayrıca şunları da yapabilirsiniz
am05mhz

Evet, aslında şunu söylüyorum: Bunun bir nesne olup olmadığını kontrol etmiyorsunuz.
İnanç Gümüş

@inanc Şerefe, ben tip kontrol yapmak için bir yol arıyordum (sadece nesne değil), bu sayfaya ve diğer sayfaya var, o zaman bu sorunun bağlamını unuttuğum için çok heyecanlandım, benim kötü :)
am05mhz
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.