Bagaimana Anda memeriksa apakah suatu nilai adalah Obyek dalam JavaScript?
Bagaimana Anda memeriksa apakah suatu nilai adalah Obyek dalam JavaScript?
Jawaban:
PEMBARUAN :
Jawaban ini tidak lengkap dan memberikan hasil yang menyesatkan . Misalnya, null
juga dianggap tipe object
dalam JavaScript, belum lagi beberapa kasus tepi lainnya. Ikuti rekomendasi di bawah ini dan lanjutkan ke "jawaban yang paling banyak dipilih (dan benar!)" Lainnya .
Jawaban asli :
Coba gunakan typeof(var)
dan / atau var instanceof something
.
EDIT: Jawaban ini memberikan ide bagaimana memeriksa properti variabel, tetapi itu bukan resep antipeluru (setelah semua tidak ada resep sama sekali!) Untuk memeriksa apakah itu objek, jauh dari itu. Karena orang cenderung mencari sesuatu untuk disalin dari sini tanpa melakukan riset, saya sangat merekomendasikan mereka beralih ke yang lain, jawaban yang paling tervotifikasi (dan benar!).
typeof
adalah operator, jadi tidak perlu ()
.
typeof
mengembalikan 'objek' untuk null, yang bukan objek, dan instanceof
tidak berfungsi untuk objek yang dibuat menggunakan Object.create(null)
.
Jika typeof yourVariable === 'object'
, itu objek atau null. Jika Anda ingin mengecualikan nol, buat saja typeof yourVariable === 'object' && yourVariable !== null
.
yourVariable !== null
praktik yang lebih baik?
typeof null == 'object'
tidak akan diperbaiki di ES6 . Mereka berkata: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
karena memiliki beberapa kasus khusus yang belum tentu masuk akal. Jika Anda mencoba membedakan antara array dan objek yang bukan array, maka Anda tentu tidak ingin menggunakannya typeof
.
Object.prototype.toString.call(yourVar)
, menjadi milik Anda apa yang perlu Anda periksa. Dalam hal array, Object.prototype.toString.call([1,2])
pengembalian[object Array]
Mari kita mendefinisikan "objek" dalam Javascript . Menurut dokumen MDN , setiap nilai adalah objek atau primitif:
primitif, nilai primitif
Data yang bukan objek dan tidak memiliki metode apa pun. JavaScript memiliki 5 tipe data primitif: string, angka, boolean, null, tidak terdefinisi.
Apa itu primitif?
3
'abc'
true
null
undefined
Apa itu objek (yaitu bukan primitif)?
Object.prototype
Object.prototype
Function.prototype
Object
Function
function C(){}
- fungsi yang ditentukan penggunaC.prototype
- properti prototipe dari fungsi yang ditentukan pengguna: ini bukan C
prototipe
new C()
- "baru" -menggunakan fungsi yang ditentukan penggunaMath
Array.prototype
{"a": 1, "b": 2}
- objek yang dibuat menggunakan notasi literalnew Number(3)
- pembungkus di sekitar primitifObject.create(null)
Object.create(null)
Cara memeriksa apakah suatu nilai adalah objek
instanceof
dengan sendirinya tidak akan berfungsi, karena merindukan dua kasus:
// oops: isObject(Object.prototype) -> false
// oops: isObject(Object.create(null)) -> false
function isObject(val) {
return val instanceof Object;
}
typeof x === 'object'
tidak akan berfungsi, karena false positive ( null
) dan false negative (functions):
// oops: isObject(Object) -> false
function isObject(val) {
return (typeof val === 'object');
}
Object.prototype.toString.call
tidak akan berfungsi, karena positif palsu untuk semua primitif:
> Object.prototype.toString.call(3)
"[object Number]"
> Object.prototype.toString.call(new Number(3))
"[object Number]"
Jadi saya menggunakan:
function isObject(val) {
if (val === null) { return false;}
return ( (typeof val === 'function') || (typeof val === 'object') );
}
@ Jawaban Daan juga sepertinya berhasil:
function isObject(obj) {
return obj === Object(obj);
}
karena, menurut dokumen MDN :
Konstruktor objek membuat pembungkus objek untuk nilai yang diberikan. Jika nilainya nol atau tidak terdefinisi, itu akan membuat dan mengembalikan objek kosong, jika tidak, itu akan mengembalikan objek tipe yang sesuai dengan nilai yang diberikan. Jika nilai sudah menjadi objek, itu akan mengembalikan nilai.
Cara ketiga yang tampaknya berhasil (tidak yakin apakah itu 100%) adalah menggunakan Object.getPrototypeOf
yang melempar pengecualian jika argumennya bukan objek:
// 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)
kembali true
untuk array.
var x = []; console.log(x === Object(x)); // return true
getPrototypeOf
tidak berfungsi misalnya dengan proksi yang dicabut, yang merupakan objek tetapi melempar.
({}).toString.apply(obj) === '[object Object]'
ini membedakan antara array dan objek yang bukan array
underscore.js menyediakan metode berikut untuk mengetahui apakah sesuatu benar-benar objek:
_.isObject = function(obj) {
return obj === Object(obj);
};
MEMPERBARUI
Karena bug sebelumnya di V8 dan optimasi kecepatan mikro kecil, metode ini terlihat sebagai berikut sejak underscore.js 1.7.0 (Agustus 2014):
_.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
juga. Seharusnya jawaban yang diterima.
Object.prototype.toString.call(myVar)
akan kembali:
"[object Object]"
jika myVar adalah objek"[object Array]"
jika myVar adalah sebuah arrayUntuk informasi lebih lanjut tentang ini dan mengapa ini merupakan alternatif yang baik untuk mengetik, lihat artikel ini .
typeof [] === 'object'
-> true
. Itulah yang Anda butuhkan dari metode ini.
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];};
Untuk hanya memeriksa terhadap Object atau Array tanpa panggilan fungsi tambahan (kecepatan). Seperti juga diposting di sini .
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 () - Catatan: gunakan hanya untuk Objek literal, karena mengembalikan false untuk objek kustom, seperti Date baru atau YourCustomObject baru.
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
hanya bekerja dengan objek literal. Jika saya membuat tipe khusus, buat instance dari tipe dan mengujinya, ia kembalifalse
Boolean(a)
lebih panjang, tetapi jauh lebih intuitif. Hanya saja, jangan gunakan new Boolean(a)
: ( inilah sebabnya )!
{
karakter. Untuk kasus array, selama Anda tidak perlu mendukung IE <9, Anda dapat menggunakan Array.isArray()
untuk menentukan apakah sesuatu array. Itu melewati semua kasus uji yang Anda berikan.
Saya sangat suka:
function isObject (item) {
return (typeof item === "object" && !Array.isArray(item) && item !== null);
}
Jika item tersebut adalah objek JS, dan itu bukan array JS, dan itu bukan null
... jika ketiganya terbukti benar, kembali true
. Jika salah satu dari tiga kondisi gagal, &&
tes akan mengalami hubungan pendek dan false
akan dikembalikan. The null
pengujian dapat dihilangkan jika diinginkan (tergantung pada bagaimana Anda menggunakan null
).
DOCS:
http://devdocs.io/javascript/operators/typeof
http://devdocs.io/javascript/global_objects/object
new Date()
mengembalikan objek. Array adalah dari sudut pandang logis bukan objek - meskipun JavaScript menangani dan melaporkannya seperti itu. Namun dalam praktiknya, tidak membantu melihat mereka sama, karena mereka tidak sama. Objek tidak memiliki length
atribut misalnya dan tidak memiliki metode seperti push (). Dan kadang-kadang Anda mungkin ingin memberikan fungsi params kelebihan beban, di mana Anda perlu membuat perbedaan antara array atau objek terutama jika parameter lain bergantung pada yang diberikan.
length
properti atau metode seperti push
, Object.create(Array.prototype)
adalah contoh tandingan sepele objek non-array yang memiliki ini. Apa yang membuat array spesial adalah bahwa mereka adalah objek eksotis dengan metode internal esensial [[DefineOwnProperty]] khusus, tetapi mereka masih objek.
length
properti (maksud saya objek literal tidak memiliki length
atribut secara default). Saya menulis bahwa array bukanlah objek dari sudut pandang logis . Saya berbicara tentang logika program. Kadang-kadang perlu untuk memeriksa apakah array adalah array "nyata" dan jelas bukan objek "nyata". Itu untuk apa Array.isArray()
. Bayangkan Anda memiliki fungsi yang menerima objek atau array objek. Memeriksa atribut atau metode khusus adalah solusi kotor. Cara asli selalu lebih baik.
typeof null
adalah "object"
, tidak "undefined"
.
Array.isArray
:function isObject(o) {
return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}
Array.isArray
:Hanya terkejut berapa banyak upvotes untuk jawaban yang salah 😮
Hanya 1 jawaban yang lulus ujian saya !!! Di sini saya telah membuat versi saya yang disederhanakan:
function isObject(o) {
return o instanceof Object && o.constructor === Object;
}
Bagi saya, itu jelas dan sederhana, dan hanya berfungsi! Di sini tes saya:
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
SATU LEBIH WAKTU: tidak semua jawaban lulus tes ini !!! 🙈
Jika Anda perlu memverifikasi bahwa objek adalah turunan dari kelas tertentu Anda harus memeriksa konstruktor dengan kelas khusus Anda, seperti:
function isDate(o) {
return o instanceof Object && o.constructor === Date;
}
tes sederhana:
var d = new Date();
console.log(isObject(d)); // Will return: false
console.log(isDate(d)); // Will return: true
Sebagai hasilnya, Anda akan memiliki kode yang ketat dan kuat!
Dalam kasus Anda tidak akan membuat fungsi seperti isDate
, isError
, isRegExp
, dll Anda dapat mempertimbangkan pilihan untuk menggunakan fungsi umum ini:
function isObject(o) {
return o instanceof Object && typeof o.constructor === 'function';
}
itu tidak akan bekerja dengan benar untuk semua kasus uji yang disebutkan sebelumnya, tetapi itu cukup baik untuk semua objek (polos atau dibangun).
isObject
tidak akan berfungsi jika Object.create(null)
implementasi internal Object.create
dijelaskan di sini tetapi Anda dapat menggunakannya isObject
dalam implementasi yang lebih canggih:
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;
};
Sudah ada paket yang dibuat di npm v1 berdasarkan implementasi ini! Dan itu bekerja untuk semua test case yang dijelaskan sebelumnya! 🙂
isDate
untukDateObject Anda dengan tujuan untuk menulis kode yang kuat jika tidak, Anda akan memiliki isObject
metode rapuh .
Date
dalam komentar saya tidak dipilih karena ya, jawabannya tidak membahas Date
. Tetapi Date
hanya salah satu dari kelas yang mungkin tak terbatas dan intinya berlaku untuk kelas lain. Contoh: class Foo() { }; var x = new Foo(); isObject(x)
kembali false
. Saya tidak tahu persis apa use case OP itu, tetapi mudah untuk memahami skenario di mana harus tahu tentang semua kelas yang mungkin dan memeriksa secara khusus terhadap masing-masing dari mereka akan menjadi tidak mungkin.
Ya Tuhan! Saya pikir ini bisa lebih pendek dari sebelumnya, mari kita lihat ini:
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
typeof objek JavaScript (termasuk null
) kembali"object"
console.log(typeof null, typeof [], typeof {})
Memeriksa constructor
fungsi pengembalian properti mereka dengan nama mereka.
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
mengembalikan nama hanya baca dari fungsi atau "anonymous"
untuk penutupan.
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
Catatan: Pada 2018, Function.name mungkin tidak berfungsi di IE https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility
Object.create(null)
dan mengapa Anda tetap melakukan itu ...?
OK, mari kita beri konsep ini dulu sebelum menjawab pertanyaan Anda, di JavaScript Fungsi adalah Object, juga null, Object, Array dan bahkan Date, jadi seperti yang Anda lihat tidak ada cara sederhana seperti typeof obj === 'object', jadi semua yang disebutkan di atas akan mengembalikan true , tetapi ada cara untuk memeriksanya dengan menulis fungsi atau menggunakan kerangka kerja JavaScript, OK:
Sekarang, bayangkan Anda memiliki objek ini yang merupakan objek nyata (bukan null atau fungsi atau array):
var obj = {obj1: 'obj1', obj2: 'obj2'};
JavaScript Murni:
//that's how it gets checked in angular framework
function isObject(obj) {
return obj !== null && typeof obj === 'object';
}
atau
//make sure the second object is capitalised
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
atau
function isObject(obj) {
return obj.constructor.toString().indexOf("Object") > -1;
}
atau
function isObject(obj) {
return obj instanceof Object;
}
Anda cukup menggunakan salah satu fungsi ini seperti di atas dalam kode Anda dengan memanggil mereka dan itu akan mengembalikan true jika itu adalah objek:
isObject(obj);
Jika Anda menggunakan kerangka kerja JavaScript, mereka biasanya telah menyiapkan fungsi semacam ini untuk Anda, ini adalah beberapa di antaranya:
jQuery:
//It returns 'object' if real Object;
jQuery.type(obj);
Sudut:
angular.isObject(obj);
Garis Bawah dan Lodash:
//(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
_.isObject(obj);
Itu tergantung pada apa yang Anda maksud dengan "adalah sebuah objek". Jika Anda ingin semua yang bukan primitif , yaitu hal-hal yang dapat Anda atur properti baru, ini harus melakukan trik:
function isAnyObject(value) {
return value != null && (typeof value === 'object' || typeof value === 'function');
}
Ini mengecualikan primitif (angka polos / NaN
/ Infinity
, string polos, simbol, true
/ false
, undefined
dan null
) tetapi harus mengembalikan true untuk yang lainnya (termasuk Number
, Boolean
dan String
objek). Perhatikan bahwa JS tidak mendefinisikan objek "host" apa, seperti window
atau console
, yang harus dikembalikan saat digunakan typeof
, sehingga sulit untuk ditutup dengan tanda centang seperti ini.
Jika Anda ingin tahu apakah sesuatu itu benda "biasa", artinya benda itu dibuat secara literal {}
atau dengan Object.create(null)
, Anda bisa melakukan ini:
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;
}
}
Sunting 2018 : Karena Symbol.toStringTag
sekarang memungkinkan menyesuaikan keluaran Object.prototype.toString.call(...)
, isPlainObject
fungsi di atas mungkin kembali false
dalam beberapa kasus bahkan ketika objek memulai hidupnya sebagai literal. Dapat diperdebatkan, dengan konvensi objek dengan tag string khusus bukan objek polos lagi, tetapi ini telah semakin memperkeruh definisi apa objek polos bahkan dalam Javascript.
instanceof Object
, dua literal fungsi identik tidak sepenuhnya sama, mereka dilewatkan dengan referensi, dll.
Ya Tuhan, terlalu banyak kebingungan dalam jawaban lain.
Jawaban singkat
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)
Untuk menguji ini cukup jalankan pernyataan berikut di konsol chrome.
Kasus 1.
var anyVar = {};
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // true
Kasus 2.
anyVar = [];
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // false
Kasus 3.
anyVar = null;
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array); // false
Penjelasan
Oke. Mari kita jabarkan
typeof anyVar == 'object'
dikembalikan benar dari tiga kandidat - [], {} and null
,
anyVar instanceof Object
mempersempit kandidat ini menjadi dua - [], {}
!(anyVar instanceof Array)
menyempit menjadi hanya satu - {}
Gulung drum!
Dengan ini, Anda mungkin sudah belajar cara memeriksa Array di Javascript.
false
(seperti yang diinginkan) ketika anyVar
suatu fungsi.
Cara paling masuk akal untuk memeriksa jenis nilai tampaknya adalah typeof
operator. Satu-satunya masalah adalah bahwa itu rusak parah:
"object"
untuk null
, yang termasuk tipe Null."function"
untuk objek yang bisa dipanggil, yang termasuk tipe objek."unknown"
. Satu-satunya hasil terlarang adalah "function"
dan tipe primitif.typeof
hanya dapat diandalkan untuk non- null
primitif. Jadi cara untuk memeriksa apakah suatu nilai adalah objek akan memastikan bahwa string yang dikembalikan oleh typeof
tidak sesuai dengan primitif, dan bahwa objek tersebut tidak null
. Namun, masalahnya adalah bahwa standar masa depan dapat memperkenalkan tipe primitif baru, dan kode kami akan menganggapnya sebagai objek. Jenis baru tidak sering muncul, tetapi misalnya ECMAScript 6 memperkenalkan jenis Simbol.
Oleh karena itu, alih-alih typeof
, saya hanya merekomendasikan pendekatan yang hasilnya bervariasi tergantung pada apakah nilainya adalah objek atau tidak. Berikut ini dimaksudkan untuk menjadi
Object
konstruktor
The Object
konstruktor memaksa argumen dilewatkan ke suatu objek. Jika sudah menjadi objek, objek yang sama dikembalikan.
Oleh karena itu, Anda dapat menggunakannya untuk memaksa nilai ke suatu objek, dan secara ketat membandingkan objek itu dengan nilai aslinya.
Fungsi berikut membutuhkan ECMAScript 3, yang memperkenalkan ===
:
function isObject(value) { /* Requires ECMAScript 3 or later */
return Object(value) === value;
}
Saya suka pendekatan ini karena sederhana dan deskriptif diri, dan cek analog juga akan berfungsi untuk boolean, angka, dan string. Namun, ketahuilah bahwa ini bergantung pada global yang Object
tidak dibayangi atau diubah.
Konstruktor
Ketika Anda instantiate konstruktor, itu bisa mengembalikan nilai yang berbeda dari contoh yang baru saja dibuat. Tetapi nilai itu akan diabaikan kecuali itu adalah objek.
Fungsi berikut membutuhkan ECMAScript 3, yang memungkinkan konstruktor untuk mengembalikan non-objek. Sebelum ECMAScript 3 yang melemparkan kesalahan, tetapi try
pernyataan tidak ada saat itu.
function isObject(value) { /* Requires ECMAScript 3 or later */
return new function() { return value; }() === value;
}
Meskipun sedikit kurang sederhana dari contoh sebelumnya, yang satu ini tidak bergantung pada properti global apa pun, dan karenanya mungkin yang paling aman.
this
nilai
Spesifikasi ECMAScript lama membutuhkan this
nilai untuk menjadi objek. ECMAScript 3 diperkenalkan Function.prototype.call
, yang memungkinkan untuk memanggil fungsi dengan this
nilai arbitrer , tetapi dipaksa untuk suatu objek.
ECMAScript 5 memperkenalkan mode ketat yang menghapus perilaku ini, tetapi dalam mode ceroboh kita masih bisa (tapi tidak boleh tidak) mengandalkannya.
function isObject(value) { /* Requires ECMAScript 3 or later in sloppy mode */
return function() { return this === value; }.call(value);
}
[[Prototipe]]
Semua objek biasa memiliki slot internal yang disebut [[Prototipe]], yang nilainya menentukan dari objek mana ia mewarisi. Nilai hanya bisa berupa objek atau null
. Oleh karena itu, Anda dapat mencoba membuat objek yang mewarisi dari nilai yang diinginkan, dan memeriksa apakah itu berfungsi.
Keduanya Object.create
dan Object.getPrototypeOf
membutuhkan ECMAScript 5.
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;
}
Beberapa cara ECMAScript 6 baru
ECMAScript 6 memperkenalkan beberapa cara tidak langsung baru untuk mengecek apakah suatu nilai adalah objek. Mereka menggunakan pendekatan yang terlihat sebelumnya untuk meneruskan nilai ke beberapa kode yang membutuhkan objek, dibungkus di dalam try
pernyataan untuk menangkap kesalahan. Beberapa contoh tersembunyi, tidak layak dikomentari
Catatan: Saya sengaja melewatkan beberapa pendekatan seperti Object.getPrototypeOf(value)
(ES5) dan Reflect
metode (ES6) karena mereka menyebut metode internal penting yang mungkin melakukan hal-hal buruk, misalnya jika value
merupakan proxy. Untuk alasan keamanan, contoh saya hanya referensi value
tanpa mengaksesnya secara langsung.
Coba ini
if (objectName instanceof Object == false) {
alert('Not an object');
}
else {
alert('An object');
}
Object.prototype instanceof Object
-> salah. Object.create(null) instanceof Object
-> salah.
new Date() instanceof Object
=> true
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
Dalam Javascript, null
, Object
, Array
, Date
dan function
s adalah semua benda. Meskipun null
sedikit dibuat-buat. Jadi, lebih baik untuk memeriksa yang null
pertama, untuk mendeteksi itu bukan nol.
Memeriksa typeof o === 'object'
jaminan yang o
merupakan objek. Tanpa pemeriksaan ini, tidak Object.prototype.toString
akan ada artinya, karena akan mengembalikan objek untuk selamanya, bahkan untuk undefined
dan null
! Sebagai contoh: toString(undefined)
kembali [object Undefined]
!
Setelah typeof o === 'object'
memeriksa, toString.call (o) adalah metode yang bagus untuk memeriksa apakah o
suatu objek, objek yang diturunkan seperti Array
, Date
atau a function
.
Secara isDerivedObject
fungsi, ia memeriksa o
fungsi. Karena, berfungsi juga sebagai objek, itu sebabnya ia ada di sana. Jika tidak melakukannya, fungsi akan kembali sebagai false. Contoh: isDerivedObject(function() {})
akan kembali false
, namun sekarang kembali true
.
Seseorang selalu dapat mengubah definisi apa itu objek. Jadi, seseorang dapat mengubah fungsi-fungsi ini sesuai.
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(){})
);
Jika Anda ingin memeriksa apakah prototype
untuk object
hanya berasal dari Object
. Menyaring String
, Number
, Array
, Arguments
, dll
function isObject (n) {
return Object.prototype.toString.call(n) === '[object Object]';
}
Atau sebagai fungsi panah ekspresi tunggal (ES6 +)
const isObject = n => Object.prototype.toString.call(n) === '[object Object]'
return Object.prototype.toString.call(n) === '[object Object]'
null
cek, karenaObject.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
Saya diminta untuk memberikan rincian lebih lanjut. Cara paling bersih dan mudah dimengerti untuk memeriksa apakah variabel kita adalah objek typeof myVar
. Ini mengembalikan string dengan tipe (misalnya "object"
, "undefined"
).
Sayangnya baik Array dan null juga memiliki tipe object
. Untuk hanya mengambil objek nyata ada kebutuhan untuk memeriksa rantai pewarisan menggunakan instanceof
operator. Ini akan menghilangkan null, tetapi Array memiliki Object dalam rantai pewarisan.
Jadi solusinya adalah:
if (myVar instanceof Object && !(myVar instanceof Array)) {
// code for objects
}
/./ instanceof Object //true
Agak terlambat ... untuk "objek biasa" (maksud saya, seperti {'x': 5, 'y': 7}) saya punya cuplikan kecil ini:
function isPlainObject(o) {
return ((o === null) || Array.isArray(o) || typeof o == 'function') ?
false
:(typeof o == 'object');
}
Ini menghasilkan output berikutnya:
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
Itu selalu berhasil untuk saya. Jika akan mengembalikan "true" hanya jika jenis "o" adalah "objek", tetapi tidak ada null, atau array, atau fungsi. :)
lodash memiliki isPlainObject , yang mungkin dicari oleh banyak orang yang datang ke halaman ini. Ini mengembalikan false ketika memberikan fungsi atau array.
_.isObject
apa yang cocok dengan apa yang JS anggap sebagai objek. Tetapi apa yang biasanya saya butuhkan adalah untuk membedakan antara misalnya objek literal dan array, yang persis apa yang _.isPlainObject
memungkinkan saya lakukan.
Ini akan bekerja Ini adalah fungsi yang mengembalikan true, false, atau mungkin null.
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
hasil untuk ujian akhir daripada false
. Lihat Kapan saya harus mengedit kode?
Karena tampaknya ada banyak kebingungan tentang bagaimana menangani masalah ini dengan benar, saya akan meninggalkan 2 sen saya (jawaban ini sesuai dengan spesifikasi dan menghasilkan hasil yang benar dalam semua keadaan):
Menguji primitif:
undefined
null
boolean
string
number
function isPrimitive(o){return typeof o!=='object'||null}
Objek bukan primitif:
function isObject(o){return !isPrimitive(o)}
Atau sebagai alternatif:
function isObject(o){return o instanceof Object}
function isPrimitive(o){return !isObject(o)}
Menguji berbagai Array:
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];
}
}());
Menguji objek tidak termasuk: Date
RegExp
Boolean
Number
String
Function
any Array
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];
}
}());
Ketika semuanya gagal, saya menggunakan ini:
var isObject = function(item) {
return item.constructor.name === "Object";
};
item.constructor === Object
?
null
melempar pengecualianUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
atau karena constructor.name
?
The Ramda perpustakaan fungsional memiliki fungsi yang indah untuk mendeteksi jenis JavaScript.
Mengutip fungsi penuh :
function type(val) {
return val === null ? 'Null' :
val === undefined ? 'Undefined' :
Object.prototype.toString.call(val).slice(8, -1);
}
Saya harus tertawa ketika saya menyadari betapa sederhana dan indah solusinya.
Contoh penggunaan dari dokumentasi Ramda :
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"
Setelah membaca dan mencoba banyak implementasi, saya telah memperhatikan bahwa sangat sedikit orang mencoba untuk memeriksa nilai-nilai seperti JSON
, Math
, document
atau benda dengan rantai prototipe lebih dari 1 langkah.
Daripada memeriksa typeof
variabel kami dan kemudian meretas kasus tepi, saya pikir akan lebih baik jika pemeriksaan dijaga sesederhana mungkin untuk menghindari keharusan refactor ketika ada primitif baru atau objek asli yang ditambahkan yang mendaftar sebagai typeof
'objek '
Lagi pula, typeof
operator akan memberi tahu Anda jika ada sesuatu yang menjadi objek JavaScript , tetapi definisi JavaScript tentang objek terlalu luas untuk sebagian besar skenario dunia nyata (mis typeof null === 'object'
.). Di bawah ini adalah fungsi yang menentukan apakah variabel v
adalah objek dengan dasarnya mengulangi dua pemeriksaan:
v
adalah '[object Object]'
. v
diganti dengan prototipe berikutnya dalam rantai dengan v = Object.getPrototypeOf(v)
, tetapi juga langsung dievaluasi setelahnya. Ketika nilai baru v
adalah null
, itu berarti bahwa setiap prototipe termasuk root prototipe (yang bisa saja merupakan satu - satunya prototipe di dalam rantai) telah lulus pemeriksaan di loop sementara dan kita dapat mengembalikan true. Kalau tidak, iterasi baru akan dimulai.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
adalah null
ini akan melemparkan kesalahan ...
false
untuk objek Object.assign({}, {constructor: null})
.
Ini adalah pertanyaan lama tetapi berpikir untuk meninggalkan ini di sini. Kebanyakan orang memeriksa apakah variabel tersebut {}
berarti kunci-nilai yang dipasangkan dan bukan apa yang digarisbawahi oleh JavaScript yang digunakan untuk suatu hal, karena jujur sebagian besar segala sesuatu dalam JavaScript adalah objek. Jadi hilangkan itu. Jika kamu melakukan...
let x = function() {}
typeof x === 'function' //true
x === Object(x) // true
x = []
x === Object(x) // true
// also
x = null
typeof null // 'object'
Sebagian besar waktu yang kita inginkan adalah untuk mengetahui apakah kita memiliki objek sumber daya dari API atau panggilan basis data kita yang dikembalikan dari ORM. Kita dapat menguji apakah bukan Array
, bukan null
, bukan tipe 'function'
, dan merupakanObject
// 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
fornew Date()
new Date()
saya menemukan cara "baru" untuk melakukan semacam ini memeriksa dari pertanyaan SO ini: Mengapa instanceof kembali false untuk beberapa literal?
dari itu, saya membuat fungsi untuk pengecekan tipe sebagai berikut:
function isVarTypeOf(_var, _type){
try {
return _var.constructor === _type;
} catch(ex) {
return false; //fallback for null or undefined
}
}
maka Anda bisa melakukan:
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
ini diuji pada Chrome 56, Firefox 52, Microsoft Edge 38, Internet Explorer 11, Opera 43
sunting:
jika Anda juga ingin memeriksa apakah suatu variabel nol atau tidak terdefinisi, Anda dapat menggunakan ini sebagai gantinya:
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
pembaruan dari komentar inanc: tantangan diterima: D
jika Anda ingin kehilangan objek perbandingan Anda dapat mencoba cara ini:
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
}
}
}
dengan begitu, Anda dapat melakukan seperti komentar inanc:
isVarTypeOf(new (function Foo(){}), Object); // returns false
isVarTypeOf(new (function Foo(){}), Object, true); // returns true
atau
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
untuk memeriksa objek. Namun, ini bukan ilmu pasti.
new Foo()
mengembalikan Foo
objek, sama seperti new String()
mengembalikan String
objek, atau new Date()
mengembalikan Date
objek, Anda Foo = function(){}; isVarTypeOf(new Foo(), Foo);
juga bisa melakukannya
null
objek).