JavaScript'te bir değerin Nesne olup olmadığını nasıl kontrol edersiniz?
JavaScript'te bir değerin Nesne olup olmadığını nasıl kontrol edersiniz?
Yanıtlar:
GÜNCELLEME :
Bu cevap eksik ve yanıltıcı sonuçlar veriyor . Örneğin, diğer bazı kenar durumlardan bahsetmemek için JavaScript null
tü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.
typeof
bir operatör, bu yüzden gerek yok ()
.
typeof
null için 'object' değerini döndürür; bu bir nesne instanceof
değildir ve kullanılarak oluşturulan nesneler için çalışmaz Object.create(null)
.
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
.
yourVariable !== null
iyi bir uygulama olur mu?
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.
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
.
Object.prototype.toString.call(yourVar)
olmak yourVar kontrol etmesi gerekenler. Diziler durumunda, Object.prototype.toString.call([1,2])
döndürür[object Array]
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
Object.prototype
Function.prototype
Object
Function
function C(){}
- kullanıcı tanımlı fonksiyonlarC.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şlevMath
Array.prototype
{"a": 1, "b": 2}
- değişmez gösterim kullanılarak oluşturulan nesnelernew Number(3)
- ilkellerin etrafındaki sarmalayıcılarObject.create(null)
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({})
obj === Object(obj)
true
diziler için döner .
var x = []; console.log(x === Object(x)); // return true
getPrototypeOf
örneğin, nesneler olan, ancak atılan iptal edilmiş proxy'lerle çalışmaz.
({}).toString.apply(obj) === '[object Object]'
Bu neden diziler ve diziler olmayan nesneler arasında ayrım yapmıyor
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;
};
return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
null
da. Kabul edilen cevap olmalı.
Object.prototype.toString.call(myVar)
geri dönücek:
"[object Object]"
myVar bir nesne ise"[object Array]"
myVar bir dizi iseBu ve neden typeof için iyi bir alternatif olduğu hakkında daha fazla bilgi için bu makaleye göz atın .
typeof [] === 'object'
-> true
. Bu yönteme ihtiyacınız var.
Object.prototype.toString.call(3)
-> "[object Number]"
. Object.prototype.toString.call(new Number(3))
-> "[object Number]
"
getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
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
isObject
yalnı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
Boolean(a)
daha uzun, ancak çok daha sezgisel. Sadece kullanmayın new Boolean(a)
: ( işte bu yüzden )!
{
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.
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 false
yapacak 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
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.
length
gibi 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.
length
özelliğe sahip olamayacağını yazdım (nesne değişmezlerinin length
varsayı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.
typeof null
olduğu "object"
değil "undefined"
.
Array.isArray
:function isObject(o) {
return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}
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.
isObject
Object.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! 🙂
isDate
sağlam kod yazmak içinDateObject için kullanmanız gerekir, aksi takdirde kırılgan isObject
yönteminiz olacaktır .
Date
kö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 .
Aman Tanrım! Bunun her zamankinden daha kısa olabileceğini düşünüyorum, şunu görelim:
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
tür JavaScript nesneleri (dahil null
) döndürür"object"
console.log(typeof null, typeof [], typeof {})
Özelliklerini kontrol constructor
etmek 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
bir 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
Object.create(null)
ve bunu neden yine de yapardınız ...?
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);
"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
/ Infinity
düz dizeleri, semboller, true
/ false
, undefined
ve null
) ama her şey (dahil olmak üzere gerçek dönmelidir Number
, Boolean
ve String
nesneler). JS'nin window
veya "gibi" hangi "ana bilgisayar" nesnelerinin console
birlikte 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(...)
, isPlainObject
yukarıdaki işlev false
bazı 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.
instanceof Object
, iki özdeş işlev değişmezi kesinlikle eşit değildir, referansla geçirilir, vb.
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.
false
olduğunda da (istendiği gibi) döner anyVar
.
Bir değerin türünü kontrol etmenin en mantıklı yolu typeof
operatör gibi görünüyor . Tek sorun, korkunç bir şekilde kırılmış olması:
"object"
için döner null
."function"
Nesne türüne ait çağrılabilir nesneler için döner ."unknown"
. Tek yasak sonuç "function"
ve ilkel tiplerdir.typeof
sadece null
ilkel 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 typeof
bir 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
Object
inşaatçı
Object
Yapı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 Object
gö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 try
ifadeler 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, this
değerin bir nesne olmasını gerektiriyordu . ECMAScript 3 tanıtıldı Function.prototype.call
, rastgele bir this
değ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.create
ve Object.getPrototypeOf
ECMAScript'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, try
hataları 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 Reflect
yöntemler (ES6) gibi bazı yaklaşımları atladım, çünkü kötü şeyler yapabilen temel iç yöntemleri çağırıyorlar, örneğin value
bir proxy ise. Güvenlik nedeniyle, örneklerim sadece value
doğrudan erişmeden referans veriyor.
Bunu dene
if (objectName instanceof Object == false) {
alert('Not an object');
}
else {
alert('An object');
}
Object.prototype instanceof Object
-> yanlış. Object.create(null) instanceof Object
-> yanlış.
new Date() instanceof Object
=> doğru
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
JavaScript yılında null
, Object
, Array
, Date
ve function
hepsi nesnelerdir. Rağmen, null
biraz yapmacık. Yani, null
ilkini kontrol etmek , boş olmadığını tespit etmek daha iyidir .
Bir nesne olan typeof o === 'object'
garantileri kontrol etmek o
. Bu kontrol olmadan, Object.prototype.toString
anlamsız olurdu, çünkü nesneyi her şey için, hatta undefined
ve 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 o
bir amacı, böyle bir türevi amacı Array
, Date
ya da function
.
In isDerivedObject
için fonksiyonunun, bu denetler o
bir 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.
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(){})
);
Eğer prototype
bir object
sadece 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]'
return Object.prototype.toString.call(n) === '[object Object]'
null
Çeki de kaldırabilirsiniz , çünküObject.prototype.toString.call(null) === '[object Null]'
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 instanceof
operatö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
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. :)
lodash isPlainObject , bu sayfaya gelen birçok kişi olabilir. Bir işlev veya dizi verirken false değerini döndürür.
_.isObject
Hangi 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 _.isPlainObject
yapmaktır.
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
null
son testin sonucu olarak elde ettim false
. Bkz. Kodda ne zaman düzenleme yapmalıyım?
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
Function
herhangi 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];
}
}());
Her şey başarısız olduğunda, bunu kullanıyorum:
var isObject = function(item) {
return item.constructor.name === "Object";
};
item.constructor === Object
?
null
bir istisna atarUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
veya yüzünden constructor.name
?
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"
Okuma ve uygulamaların bir sürü denedikten sonra, çok az insan gibi değerleri denetlemek için deneyin fark ettik JSON
, Math
, document
1 adım daha uzun prototip zincirleri ile veya nesneler.
typeof
Değ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, typeof
operatö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, v
iki denetimi tekrarlayarak değişkenin bir nesne olup olmadığını belirleyen bir işlev vardır :
v
olduğunu '[object Object]'
. v
zincirindeki bir sonraki prototip ile değiştirilir v = Object.getPrototypeOf(v)
, ancak sonradan doğrudan değerlendirilir. Yeni değeri v
olduğ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'}))))
if(typeof value === 'object' && value.constructor === Object)
{
console.log("This is an object");
}
value
olduğu null
bu bir hata atar ...
false
nesne için olacak Object.assign({}, {constructor: null})
.
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 Array
değ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
true
içinnew Date()
new Date()
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
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
instanceof
nesneleri kontrol etmek için kullanabilirsiniz . Yine de, bu tam bir bilim değil.
new Foo()
bir Foo
nesneyi new String()
döndürür, bir String
nesneyi new Date()
döndürür veya bir Date
nesneyi döndürür , Foo = function(){}; isVarTypeOf(new Foo(), Foo);
ayrıca şunları da yapabilirsiniz
null
, bir nesne olup olmadığı ).