Periksa apakah suatu nilai adalah objek dalam JavaScript

1365

Bagaimana Anda memeriksa apakah suatu nilai adalah Obyek dalam JavaScript?

Danny Fox
sumber
4
Variabel adalah variabel. Ini mungkin merujuk ke suatu objek. Juga, Anda mungkin ingin mendefinisikan "objek" - seperti yang ditunjukkan oleh jawaban dan komentar, ada berbagai definisi yang saling bertentangan (misalnya apakah nullobjek).
8
OP, IMO Anda harus menerima jawaban @ Daan karena ini adalah solusi terbaik dan harus terdaftar di atas jawaban lain sehingga terlihat pertama. (Jangan tersinggung orang lain yang juga memiliki jawaban yang baik.)
tiffon
2
IMHO itu benar-benar tergantung pada apa yang Anda (yang mencari jawaban untuk pertanyaan ini) mempertimbangkan sebuah Objek, dan mengapa Anda memeriksanya. Pertanyaan ini memberikan jawaban yang berbeda jika Anda mencoba untuk membedakan Array (yang adalah Objects) dari lainnya Objects atau jika Anda mencoba untuk memisahkan nilai-nilai skalar dari "vektor". Dan apakah nol (yang merupakan Obyek, menurut typeof) atau Fungsi (yang adalah Objects) harus dikecualikan atau tidak, itu benar-benar tergantung pada mengapa Anda memeriksa itu. Itu sebabnya ada begitu banyak jawaban dan sebagian besar dari mereka, dalam konteksnya, benar.
FrancescoMM
const isEmpty = thing => {typeof thing === "object"? ! Hal || ! Object.keys (thing) .length:! Thing && thing! == 0};
Mayur S
1
Akan lebih bagus jika Anda bisa mulai dengan mengatakan apa yang sebenarnya Anda maksud dengan "adalah Obyek". (Atau, katakan secara eksplisit bahwa bagian dari jawaban yang Anda cari adalah untuk menemukan berbagai arti populer dari "adalah sebuah objek" dan kemudian bedakan di antara mereka.) Karena itu, semua orang berbicara melewati satu sama lain.
Don Hatch

Jawaban:

520

PEMBARUAN :

Jawaban ini tidak lengkap dan memberikan hasil yang menyesatkan . Misalnya, nulljuga dianggap tipe objectdalam 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!).

Michael Krelin - hacker
sumber
208
typeofadalah operator, jadi tidak perlu ().
Yoshi
67
Ya, tidak perlu. Saya hanya lebih suka seperti ini.
Michael Krelin - hacker
150
@ MichaelKrelin-hacker: Itu disayangkan karena membingungkan orang .
RightSaidFred
11
@RightSaidFred, saya tidak punya penjelasan untuk itu, tapi saya sama sekali tidak cenderung untuk menambahkan tanda kurung tambahan dalam ekspresi ini :)
Michael Krelin - hacker
117
Jawaban ini salah. typeofmengembalikan 'objek' untuk null, yang bukan objek, dan instanceoftidak berfungsi untuk objek yang dibuat menggunakan Object.create(null).
Nikolai
1635

Jika typeof yourVariable === 'object', itu objek atau null. Jika Anda ingin mengecualikan nol, buat saja typeof yourVariable === 'object' && yourVariable !== null.

Membuang
sumber
31
Fungsi juga objek dan harus dimasukkan dalam cek Anda.
JS_Riddler
4
Dalam hal ini akankah yourVariable !== nullpraktik yang lebih baik?
hippietrail
9
@RightSaidFred Tampaknya 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.
Konstantin Smolyanin
2
@Orion, jawaban sederhananya adalah array dianggap sebagai objek. Untuk jawaban yang lebih terperinci, Anda harus membaca terus typeofkarena 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.
Matt Fenwick
8
@Tresdin Cara terbaik adalah berlari 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]
Jose Rui Santos
539

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
  • semuanya berasal dari Object.prototype
    • Function.prototype
      • Object
      • Function
      • function C(){} - fungsi yang ditentukan pengguna
    • C.prototype- properti prototipe dari fungsi yang ditentukan pengguna: ini bukan C prototipe
      • new C() - "baru" -menggunakan fungsi yang ditentukan pengguna
    • Math
    • Array.prototype
      • array
    • {"a": 1, "b": 2} - objek yang dibuat menggunakan notasi literal
    • new Number(3) - pembungkus di sekitar primitif
    • ... banyak hal lain ...
  • Object.create(null)
  • semuanya turun dari 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.getPrototypeOfyang 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({})
Matt Fenwick
sumber
22
obj === Object(obj)kembali trueuntuk array.
Onur Yıldırım
5
var x = []; console.log(x === Object(x)); // return true
Illuminator
6
@Illuminator array adalah objek dalam Javascript, seperti yang saya sebutkan dalam jawaban saya.
Matt Fenwick
1
getPrototypeOftidak berfungsi misalnya dengan proksi yang dicabut, yang merupakan objek tetapi melempar.
Oriol
2
Mengapa tidak ({}).toString.apply(obj) === '[object Object]'ini membedakan antara array dan objek yang bukan array
MauricioJuanes
295

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;
};
Daan
sumber
57
Dalam javascript array juga merupakan objek, jadi sebagian besar waktu Anda ingin mengecualikan array:return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
Daan
22
mengapa Anda mengecualikan array? Mereka adalah benda penuh.
Nikolai
65
Karena sebagian besar waktu Anda ingin membedakan suatu {} dari suatu [] misalnya sebagai input dalam suatu fungsi
Daan
5
@Nickolai ..dan untuk iterasi melalui objek bersarang.
Ricky Boyce
6
Jawaban yang bagus Menangani nulljuga. Seharusnya jawaban yang diterima.
tiffon
180

Object.prototype.toString.call(myVar) akan kembali:

  • "[object Object]" jika myVar adalah objek
  • "[object Array]" jika myVar adalah sebuah array
  • dll.

Untuk informasi lebih lanjut tentang ini dan mengapa ini merupakan alternatif yang baik untuk mengetik, lihat artikel ini .

Christophe
sumber
12
Saya baru-baru belajar bahwa typeof [] === 'object'-> true. Itulah yang Anda butuhkan dari metode ini.
Jondlm
3
@Christophe Tidak membedakan antara primitif dan objek . Object.prototype.toString.call(3)-> "[object Number]". Object.prototype.toString.call(new Number(3))-> "[object Number]"
Matt Fenwick
3
@MattFenwick Saya tidak berpikir ini adalah semacam "objek" yang coba diidentifikasi oleh OP
Christophe
3
@ Christophe mengapa Anda berpikir begitu? IMHO, dengan tidak adanya definisi lain yang diberikan oleh OP untuk "objek", tampaknya paling masuk akal bagi saya untuk pergi dengan yang digunakan secara konsisten di seluruh spesifikasi ECS.
Matt Fenwick
getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
Tn. Polywhirl
116

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
zupa
sumber
isObjecthanya bekerja dengan objek literal. Jika saya membuat tipe khusus, buat instance dari tipe dan mengujinya, ia kembalifalse
WickyNilliams
3
@ zupa: apa !! a tidak?
4
@ 3000 baik, jika kita meninggalkan bagian (!! a) itu crash, karena nol dan tidak terdefinisi tidak memiliki konstruktor. (!! a) memfilternya. Apakah itu menjawab pertanyaan Anda?
zupa
2
@ zupa @ 3000 Boolean(a)lebih panjang, tetapi jauh lebih intuitif. Hanya saja, jangan gunakan new Boolean(a): ( inilah sebabnya )!
JayVee
10
Terkejut jawaban terbaiknya adalah sejauh ini. Ini pada dasarnya menjawab pertanyaan - apakah ini diwakili dalam JSON sebagai sesuatu yang dimulai dengan {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.
Kip
81

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 falseakan dikembalikan. The nullpengujian dapat dihilangkan jika diinginkan (tergantung pada bagaimana Anda menggunakan null).

DOCS:

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

2540625
sumber
3
Bagaimana dengan console.log (isObject (Date baru ()))? Mengapa kencan harus menjadi objek tetapi array tidak?
schirrmacher
5
@macher Karena 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 lengthatribut 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.
StanE
1
@StanE Arrays jelas merupakan objek. Tidak yakin mengapa Anda berpikir objek tidak dapat memiliki lengthproperti 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.
Oriol
4
@Oriol Saya tidak menulis bahwa array bukanlah objek dan saya juga tidak menulis bahwa objek tidak dapat memiliki lengthproperti (maksud saya objek literal tidak memiliki lengthatribut 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.
StanE
2
typeof nulladalah "object", tidak "undefined".
2540625
80

Dengan fungsi Array.isArray:

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

Tanpa fungsi 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).


isObjecttidak akan berfungsi jika Object.create(null)implementasi internal Object.createdijelaskan di sini tetapi Anda dapat menggunakannya isObjectdalam 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! 🙂

V. Kovpak
sumber
jawaban Terbaik! berfungsi untuk banyak kasus yang disebutkan di sini
prieston
Karena ini mengembalikan false untuk isObject (myDateObject), ini bukan jawaban untuk pertanyaan. Itu tidak mengatakan apakah suatu variabel adalah objek, hanya jika itu adalah objek dari kelas tertentu. Pertanyaannya di sini adalah untuk fungsi generik yang mengembalikan true untuk objek apa pun.
Yetanotherjosh
@Yetanotherjosh Ini memang jawaban 🤓 Anda menyebutkan kasus yang dijelaskan dalam jawaban, dan intinya - Anda harus menggunakan isDateuntukDateObject Anda dengan tujuan untuk menulis kode yang kuat jika tidak, Anda akan memiliki isObjectmetode rapuh .
V. Kovpak
@VladimirKovpak Menggunakan Datedalam komentar saya tidak dipilih karena ya, jawabannya tidak membahas Date. Tetapi Datehanya 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.
Yetanotherjosh
@Yetanotherjosh Saya sudah memperbarui jawaban saya. Dan menambahkan 1 case lagi.
V. Kovpak
41

Ya Tuhan! Saya pikir ini bisa lebih pendek dari sebelumnya, mari kita lihat ini:

Kode pendek dan final

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

Dijelaskan

Jenis pengembalian

typeof objek JavaScript (termasuk null) kembali"object"

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

Memeriksa konstruktor mereka

Memeriksa constructorfungsi 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

Memperkenalkan Function.name

Function.namemengembalikan 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

Erisan Olasheni
sumber
3
Saya sangat suka yang ini, pendek dan to the point. Itu hanya gagal pada 1 hal sejauh yang saya bisa lihat. jika obj = Object.create(null)dan mengapa Anda tetap melakukan itu ...?
Julian Knight
29

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);
Alireza
sumber
Anda juga ingin memeriksa apakah itu bukan array. jadi fungsi isObject (obj) {return obj! == null && typeof obj === 'objek' &&! Array.isArray (obj); }
Matt Goo
Saya setuju dengan Anda, tetapi seperti yang Anda lihat di komentar, ini adalah bagaimana hal itu dilakukan dalam angularJs dan saya menyebutkannya di komentar di depan fungsi, mereka menghitung Array sebagai Objek ... lihat di sini untuk informasi lebih lanjut: docs .angularjs.org / api / ng / function / angular.isObject
Alireza
24

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, undefineddan null) tetapi harus mengembalikan true untuk yang lainnya (termasuk Number, Booleandan Stringobjek). Perhatikan bahwa JS tidak mendefinisikan objek "host" apa, seperti windowatau 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.toStringTagsekarang memungkinkan menyesuaikan keluaran Object.prototype.toString.call(...), isPlainObjectfungsi di atas mungkin kembali falsedalam 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.

anak terakhir
sumber
Mengapa typeof === 'function' dianggap sebagai objek? Fungsi bukan objek, bukan? "new myFunc ()" akan menjadi objek, ya, tapi fungsi sederhana?
StanE
Tidak, setiap fungsi adalah objek dalam Javascript, terlepas dari bagaimana ia dibuat. Anda dapat mengatur properti pada mereka (kecuali jika mereka dibekukan), mereka adalah instanceof Object, dua literal fungsi identik tidak sepenuhnya sama, mereka dilewatkan dengan referensi, dll.
child-last
21

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.

kushalvm
sumber
2
Sebagai catatan, ini juga mengembalikan false(seperti yang diinginkan) ketika anyVarsuatu fungsi.
Jamie Birch
18

Cara paling masuk akal untuk memeriksa jenis nilai tampaknya adalah typeofoperator. Satu-satunya masalah adalah bahwa itu rusak parah:

  • Itu kembali "object"untuk null, yang termasuk tipe Null.
  • Ini mengembalikan "function"untuk objek yang bisa dipanggil, yang termasuk tipe objek.
  • Ia dapat mengembalikan (hampir) apapun yang diinginkan untuk objek non-callable non-standar. Misalnya, IE sepertinya suka "unknown". Satu-satunya hasil terlarang adalah "function"dan tipe primitif.

typeofhanya dapat diandalkan untuk non- nullprimitif. Jadi cara untuk memeriksa apakah suatu nilai adalah objek akan memastikan bahwa string yang dikembalikan oleh typeoftidak 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

Daftar lengkap namun tidak lengkap tentang cara yang tepat untuk menguji apakah suatu nilai termasuk dalam tipe Objek.

  • Object konstruktor

    The Objectkonstruktor 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 Objecttidak 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 trypernyataan 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 thisnilai untuk menjadi objek. ECMAScript 3 diperkenalkan Function.prototype.call, yang memungkinkan untuk memanggil fungsi dengan thisnilai 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.createdan Object.getPrototypeOfmembutuhkan 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 trypernyataan untuk menangkap kesalahan. Beberapa contoh tersembunyi, tidak layak dikomentari


Catatan: Saya sengaja melewatkan beberapa pendekatan seperti Object.getPrototypeOf(value)(ES5) dan Reflectmetode (ES6) karena mereka menyebut metode internal penting yang mungkin melakukan hal-hal buruk, misalnya jika valuemerupakan proxy. Untuk alasan keamanan, contoh saya hanya referensi valuetanpa mengaksesnya secara langsung.

Oriol
sumber
2
"Hanya jawabanku dan Daan yang sepenuhnya benar." agak sombong mengingat bahwa saya sepenuhnya tidak setuju dengan dua kalimat pertama Anda.
zzzzBov
1
@zzzzBov Yah, saya melihat semua jawaban dan mereka tidak memastikan untuk selalu mengembalikan jawaban yang tepat, kecuali jawaban saya dan Daan. Saya dapat memberikan contoh tandingan yang dapat direproduksi kepada kebanyakan dari mereka. Yang lain merekomendasikan memeriksa apakah typeof mengembalikan "fungsi" atau "objek", tetapi seperti yang saya jelaskan, spec memungkinkan hasil lain untuk beberapa objek. Jawaban Matt Fenwick berisi jawaban yang benar sama dengan jawaban Daan, tetapi juga berisi jawaban yang salah.
Oriol
1
Saya tidak setuju dengan premis bahwa jawaban Anda "sepenuhnya benar", dengan alasan bahwa orang lain "tidak memastikan untuk selalu mengembalikan jawaban yang tepat" tidak membantah posisi saya dengan cara apa pun. Selain itu, pertanyaannya tidak membuat klaim tentang input apa yang harus menghasilkan output apa.
zzzzBov
1
@zzzzBov Pertanyaannya menanyakan bagaimana memeriksa apakah sesuatu itu objek. ECMAScript mendefinisikan apa objek itu, jadi saya menggunakan definisi itu. Saya tidak bisa melihat interpretasi lain yang masuk akal. Jawaban yang melakukan hal-hal lain (seperti mengecualikan array) dapat berguna dalam beberapa keadaan, tetapi mereka tidak memeriksa apakah ada sesuatu yang objek.
Oriol
@Oriol Mungkin Anda bisa memberikan jawaban untuk pertanyaan ini. Mengapa tidak ada metode bawaan dalam JavaScript untuk memeriksa apakah suatu objek adalah objek biasa? ?
tamu271314
15

Coba ini

if (objectName instanceof Object == false) {
  alert('Not an object');
}
else {
  alert('An object');
}
Talha
sumber
14
Mengapa Anda harus memeriksa boolean?
jkutianski
5
Ini merindukan dua kasus: Object.prototype instanceof Object-> salah. Object.create(null) instanceof Object-> salah.
Matt Fenwick
bagaimana dengan kencan? new Date() instanceof Object => true
mauron85
13

Fungsi siap pakai untuk memeriksa

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

Penjelasan

  • Dalam Javascript, null, Object, Array, Datedan functions adalah semua benda. Meskipun nullsedikit dibuat-buat. Jadi, lebih baik untuk memeriksa yang nullpertama, untuk mendeteksi itu bukan nol.

  • Memeriksa typeof o === 'object'jaminan yang omerupakan objek. Tanpa pemeriksaan ini, tidak Object.prototype.toStringakan ada artinya, karena akan mengembalikan objek untuk selamanya, bahkan untuk undefineddan null! Sebagai contoh: toString(undefined)kembali [object Undefined]!

    Setelah typeof o === 'object'memeriksa, toString.call (o) adalah metode yang bagus untuk memeriksa apakah osuatu objek, objek yang diturunkan seperti Array, Dateatau a function.

  • Secara isDerivedObjectfungsi, ia memeriksa ofungsi. 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.


Tes

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(){})
);

Inanc Gumus
sumber
13

Jika Anda ingin memeriksa apakah prototypeuntuk objecthanya 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]'
sasi
sumber
1
ini adalah cara terbaik tapi saya akan membuatnya lebih mudah dengan pada baris ke-2:return Object.prototype.toString.call(n) === '[object Object]'
mesqueeb
1
Anda juga dapat menghapus nullcek, karenaObject.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

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 instanceofoperator. Ini akan menghilangkan null, tetapi Array memiliki Object dalam rantai pewarisan.

Jadi solusinya adalah:

if (myVar instanceof Object && !(myVar instanceof Array)) {
  // code for objects
}
Kania
sumber
/./ instanceof Object //true
yckart
11

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. :)

Emilio Grisolía
sumber
Seperti disebutkan dalam jawaban sebelumnya, pendekatan Anda akan gagal jika ada objek Date.
Grzegorz Pawlik
9

lodash memiliki isPlainObject , yang mungkin dicari oleh banyak orang yang datang ke halaman ini. Ini mengembalikan false ketika memberikan fungsi atau array.

Menepuk
sumber
Sempurna! Saya tahu tentang _.isObjectapa 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 _.isPlainObjectmemungkinkan saya lakukan.
kapur
9

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

pizzarob
sumber
2
@SeregPie Di masa mendatang Anda harus menahan diri dari mengedit kode sebagai jawaban. Sebagai jawaban ini berdiri, ketika pengujian saya memang mendapatkan nullhasil untuk ujian akhir daripada false. Lihat Kapan saya harus mengedit kode?
Nick
9

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 Functionany 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];
    }
}());
c7x43t
sumber
8

Ketika semuanya gagal, saya menggunakan ini:

var isObject = function(item) {
   return item.constructor.name === "Object";
}; 
Michal
sumber
1
Mengapa perbandingan string, mengapa tidak sederhana item.constructor === Object?
K3 --- rnc
nullmelempar pengecualianUncaught TypeError: Cannot read property 'constructor' of null(…)
Vitim.us
@rounce Saya bertujuan untuk mendukung versi IE yang lebih lama, mengapa tidak bekerja di IE? Karena indexOfatau karena constructor.name?
Jankapunkt
8

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"
DaveGauer
sumber
8

Setelah membaca dan mencoba banyak implementasi, saya telah memperhatikan bahwa sangat sedikit orang mencoba untuk memeriksa nilai-nilai seperti JSON, Math, documentatau benda dengan rantai prototipe lebih dari 1 langkah.

Daripada memeriksa typeofvariabel 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, typeofoperator 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 vadalah objek dengan dasarnya mengulangi dua pemeriksaan:

  1. Sebuah loop dimulai yang berlanjut selama versi string vadalah '[object Object]'.
    Saya ingin hasil fungsi persis seperti log di bawah ini, jadi ini adalah satu-satunya "objektivitas" -kriteria yang saya dapatkan. Jika gagal, fungsi mengembalikan false segera.
  2. vdiganti dengan prototipe berikutnya dalam rantai dengan v = Object.getPrototypeOf(v), tetapi juga langsung dievaluasi setelahnya. Ketika nilai baru vadalah 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'}))))

Gust van de Wal
sumber
6
if(typeof value === 'object' && value.constructor === Object)
{
    console.log("This is an object");
}
Mahak Choudhary
sumber
1
Jika valueadalah nullini akan melemparkan kesalahan ...
Gersom
Dan tentu saja itu falseuntuk objek Object.assign({}, {constructor: null}).
user4642212
6

Jika secara eksplisit ingin memeriksa apakah nilai yang diberikan adalah {}.

function isObject (value) {
 return value && typeof value === 'object' && value.constructor === Object;
}
Carlos
sumber
6
const isObject = function(obj) {
  const type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};

!!objadalah singkatan untuk memeriksa apakah objbenar (untuk menyaring null)

Ira
sumber
6

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
Gilbert
sumber
pops truefornew Date()
toddmo
1
@toddmo terima kasih telah menunjukkannya. Sekarang kode contoh mengembalikan false untuknew Date()
Gilbert
4

Yang saya suka gunakan adalah ini

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

Saya pikir dalam sebagian besar kasus Tanggal harus lulus cek sebagai Obyek, jadi saya tidak menyaring tanggal

JohnPan
sumber
4

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
am05mhz
sumber
Ini tidak dapat mendeteksi apakah kelas baru adalah objek. isVarTypeOf (baru (function Foo () {}), Object) // Ini mengembalikan false bukan true. Lihat jawaban saya di bawah ini untuk pemeriksaan yang tepat.
Inanc Gumus
Namun, Anda dapat menggunakannya instanceofuntuk memeriksa objek. Namun, ini bukan ilmu pasti.
Inanc Gumus
@inanc, yah itu karena new Foo()mengembalikan Fooobjek, sama seperti new String()mengembalikan Stringobjek, atau new Date()mengembalikan Dateobjek, Anda Foo = function(){}; isVarTypeOf(new Foo(), Foo);juga bisa melakukannya
am05mhz
Ya, itulah yang sebenarnya saya katakan: Anda tidak memeriksa apakah itu objek saat ini.
Inanc Gumus
@inanc Cheers, saya sedang mencari cara untuk melakukan pengecekan tipe (bukan hanya objek), sampai ke halaman ini dan halaman lainnya, kemudian saya menjadi terlalu bersemangat sehingga saya lupa konteks pertanyaan ini, salah saya :)
am05mhz