Kiểm tra xem một giá trị có phải là một đối tượng trong JavaScript không


1365

Làm cách nào để kiểm tra xem giá trị có phải là Đối tượng trong JavaScript không?


4
Một biến là một biến. Nó có thể đề cập đến một đối tượng. Ngoài ra, bạn có thể muốn xác định "đối tượng" - như câu trả lời và nhận xét cho thấy, có nhiều định nghĩa mâu thuẫn khác nhau (ví dụ: có phải nulllà một đối tượng) hay không.

8
OP, IMO bạn nên chấp nhận câu trả lời của @ Daan vì đây là giải pháp tốt nhất và nên được liệt kê ở trên các câu trả lời khác để nó được nhìn thấy đầu tiên. (Không xúc phạm đến những người khác cũng có câu trả lời hay.)
tt

2
IMHO nó thực sự phụ thuộc vào những gì bạn (người tìm kiếm câu trả lời cho câu hỏi này) xem xét một Đối tượng và lý do tại sao bạn đang kiểm tra nó. Câu hỏi này đưa ra các câu trả lời khác nhau nếu bạn đang cố phân biệt Mảng (đó Đối tượng) với các Đối tượng khác hoặc nếu bạn đang cố tách các giá trị vô hướng khỏi "vectơ". Và liệu null (đó một Object, theo typeof) hay Hàm (đó Object) nên được loại trừ hay không, nó thực sự phụ thuộc vào lý do tại sao bạn kiểm tra nó. Đó là lý do tại sao có rất nhiều câu trả lời và hầu hết trong số đó, trong bối cảnh, là chính xác.
FrancescoMM

const isEmpty = thing => {typeof thing === "object"? ! điều | | ! Object.keys (điều) .length :! Điều && điều! == 0};
Mayur S

1
Sẽ thật tuyệt nếu bạn có thể bắt đầu bằng cách nói chính xác ý của bạn là "là một đối tượng". (Hoặc, nói một cách rõ ràng rằng một phần của câu trả lời bạn đang tìm kiếm là tìm hiểu những ý nghĩa phổ biến khác nhau của "là một đối tượng" và sau đó phân biệt giữa chúng.) Thiếu điều đó, mọi người đang nói chuyện với nhau.
Don nở

Câu trả lời:


520

CẬP NHẬT :

Câu trả lời này không đầy đủ và cho kết quả sai lệch . Ví dụ, nullcũng được xem là loại objecttrong JavaScript, chưa kể một số trường hợp cạnh khác. Thực hiện theo khuyến nghị bên dưới và chuyển sang câu trả lời "được đánh giá cao nhất (và chính xác!)" Khác .


Câu trả lời gốc :

Hãy thử sử dụng typeof(var)và / hoặc var instanceof something.

EDIT: Câu trả lời này đưa ra ý tưởng về cách kiểm tra các thuộc tính của biến, nhưng nó không phải là một công thức chống đạn (sau tất cả không có công thức nào cả!) Để kiểm tra xem đó có phải là một vật thể, cách xa nó không. Vì mọi người có xu hướng tìm kiếm thứ gì đó để sao chép từ đây mà không thực hiện bất kỳ nghiên cứu nào, tôi rất khuyến nghị họ nên chuyển sang câu trả lời khác, được đánh giá cao nhất (và chính xác!).


208
typeoflà một nhà điều hành, vì vậy không cần ().
Yoshi

67
Có, không cần. Tôi chỉ thích nó theo cách này.
Michael Krelin - hacker

150
@ MichaelKrelin-hacker: Thật không may vì nó làm mọi người bối rối .
RightSaidFred

11
@RightSaidFred, tôi không có lời giải thích nào cho nó, nhưng tôi hoàn toàn không có xu hướng thêm dấu ngoặc trong các biểu thức này :)
Michael Krelin - hacker

117
Câu trả lời này không chính xác. typeoftrả về 'đối tượng' cho null, không phải là một đối tượng và instanceofkhông hoạt động đối với các đối tượng được tạo bằng cách sử dụng Object.create(null).
Nikolai

1635

Nếu typeof yourVariable === 'object', nó là một đối tượng hoặc null. Nếu bạn muốn loại trừ null, chỉ cần làm cho nó typeof yourVariable === 'object' && yourVariable !== null.


31
Các chức năng cũng là đối tượng và nên được bao gồm trong kiểm tra của bạn.
JS_Riddler

4
Trong trường hợp này sẽ yourVariable !== nullđược thực hành tốt hơn?
hà mã

9
@RightSaidFred Có vẻ như typeof null == 'object'sẽ không được sửa trong ES6 . Họ nói: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
@Hoặc câu trả lời đơn giản là mảng được coi là đối tượng. Để có câu trả lời chi tiết hơn, bạn sẽ phải đọc tiếp typeofvì nó có một vài trường hợp đặc biệt không nhất thiết phải có nhiều ý nghĩa. Nếu bạn đang cố phân biệt giữa các mảng và các đối tượng không phải là mảng, thì bạn chắc chắn không muốn sử dụng typeof.
Matt Fenwick

8
@Tresdin Cách tốt nhất là để chạy Object.prototype.toString.call(yourVar), là yourVar những gì bạn cần phải kiểm tra. Trong trường hợp mảng, Object.prototype.toString.call([1,2])trả lại[object Array]
Jose Rui Santos

539

Hãy xác định "đối tượng" trong Javascript . Theo các tài liệu MDN , mọi giá trị là một đối tượng hoặc nguyên thủy:

nguyên thủy, giá trị nguyên thủy

Dữ liệu không phải là đối tượng và không có bất kỳ phương thức nào. JavaScript có 5 kiểu dữ liệu nguyên thủy: chuỗi, số, boolean, null, không xác định.

Nguyên thủy là gì?

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

Đối tượng là gì (tức không phải là nguyên thủy)?

  • Object.prototype
  • mọi thứ bắt nguồn từ Object.prototype
    • Function.prototype
      • Object
      • Function
      • function C(){} - các hàm do người dùng định nghĩa
    • C.prototype- thuộc tính nguyên mẫu của hàm do người dùng xác định: đây không phải C là nguyên mẫu
      • new C() - "mới" -ing một chức năng do người dùng xác định
    • Math
    • Array.prototype
      • mảng
    • {"a": 1, "b": 2} - các đối tượng được tạo bằng ký hiệu bằng chữ
    • new Number(3) - bao bọc xung quanh nguyên thủy
    • ... nhiều thứ khác ...
  • Object.create(null)
  • tất cả mọi thứ đi xuống từ một Object.create(null)

Cách kiểm tra xem giá trị có phải là một đối tượng không

instanceof tự nó sẽ không hoạt động, vì nó bỏ lỡ hai trường hợp:

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

typeof x === 'object'sẽ không hoạt động, vì dương tính giả ( null) và âm tính giả (hàm):

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

Object.prototype.toString.call sẽ không hoạt động, vì tích cực sai cho tất cả các nguyên thủy:

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

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

Vì vậy, tôi sử dụng:

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

Câu trả lời của Daan dường như cũng có tác dụng:

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

bởi vì, theo các tài liệu MDN :

Hàm tạo đối tượng tạo một trình bao bọc đối tượng cho giá trị đã cho. Nếu giá trị là null hoặc không xác định, nó sẽ tạo và trả về một đối tượng trống, nếu không, nó sẽ trả về một đối tượng thuộc loại tương ứng với giá trị đã cho. Nếu giá trị là một đối tượng đã có, nó sẽ trả về giá trị.


Cách thứ ba có vẻ hiệu quả (không chắc là 100%) là sử dụng Object.getPrototypeOfđể ném ngoại lệ nếu đối số của nó không phải là đối tượng:

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

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

22
obj === Object(obj)trả về truecho mảng.
Onur Yıldırım

5
var x = []; console.log(x === Object(x)); // return true
Đèn chiếu sáng

6
Mảng @Illuminator các đối tượng trong Javascript, như tôi đã đề cập trong câu trả lời của mình.
Matt Fenwick

1
getPrototypeOfkhông hoạt động, ví dụ với các proxy bị thu hồi, là các đối tượng nhưng ném.
Oriol

2
Tại sao ({}).toString.apply(obj) === '[object Object]'điều này không phân biệt giữa các mảng và các đối tượng không phải là mảng
MauricioJuanes

295

underscore.js cung cấp phương thức sau để tìm hiểu xem có thứ gì đó thực sự là một đối tượng không:

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

CẬP NHẬT

Do một lỗi trước đó trong V8 và tối ưu hóa tốc độ vi mô nhỏ, phương thức này trông như sau kể từ underscore.js 1.7.0 (tháng 8 năm 2014):

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

57
Trong javascript, một mảng cũng là một đối tượng, vì vậy, hầu hết thời gian bạn muốn loại trừ mảng:return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
Daan

22
Tại sao bạn lại loại trừ một mảng? Họ là những đối tượng chính thức.
Nikolai

65
Bởi vì hầu hết thời gian bạn muốn phân biệt {} với [] chẳng hạn như đầu vào trong một hàm
Daan

5
@Nickolai .. và để lặp qua các đối tượng lồng nhau.
Ricky Boyce

6
Câu trả lời chính xác. Xử lý null, quá. Nên là câu trả lời được chấp nhận.
tiffon

180

Object.prototype.toString.call(myVar) sẽ trở lại:

  • "[object Object]" nếu myVar là một đối tượng
  • "[object Array]" nếu myVar là một mảng
  • Vân vân.

Để biết thêm thông tin về điều này và tại sao nó là một thay thế tốt cho typeof, hãy xem bài viết này .


12
Gần đây tôi đã học được rằng typeof [] === 'object'-> true. Đó là những gì bạn cần phương pháp này.
Jondlm

3
@Christophe Không phân biệt giữa nguyên thủy và đối tượng . Object.prototype.toString.call(3)-> "[object Number]". Object.prototype.toString.call(new Number(3))-> "[object Number]"
Matt Fenwick

3
@MattFenwick Tôi không nghĩ rằng đây là loại "đối tượng" OP đang cố gắng xác định
Christophe

3
@Christophe tại sao bạn nghĩ vậy? IMHO, trong trường hợp không có bất kỳ định nghĩa nào khác được đưa ra bởi OP cho "đối tượng", đối với tôi, có vẻ hợp lý nhất với định nghĩa được sử dụng nhất quán trong toàn bộ thông số ECS.
Matt Fenwick

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

116

Để kiểm tra đơn giản đối với Object hoặc Array mà không cần gọi hàm (tốc độ) bổ sung. Như cũng được đăng ở đây .

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 () - Lưu ý: chỉ sử dụng cho các đối tượng bằng chữ, vì nó trả về false cho các đối tượng tùy chỉnh, như Ngày mới hoặc YourCustomObject mới.

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

isObjectchỉ hoạt động với các đối tượng bằng chữ. Nếu tôi tạo một loại tùy chỉnh, hãy tạo một thể hiện của loại đó và kiểm tra nó, nó sẽ trả vềfalse
WickyNilliams

3
@zupa: cái gì !!

4
@ 3000 tốt, nếu chúng ta bỏ qua phần (!! a) thì nó bị hỏng, vì null và không xác định không có hàm tạo. (!! a) lọc chúng ra. Câu trả lời đó có đáp ứng được câu hỏi của bạn không?
zupa

2
@zupa @ 3000 Boolean(a)dài hơn, nhưng trực quan hơn nhiều. Chỉ không sử dụng new Boolean(a): ( đây là lý do )!
JayVee

10
Ngạc nhiên câu trả lời tốt nhất là cho đến nay xuống trang. Điều này về cơ bản trả lời câu hỏi - điều này sẽ được biểu diễn trong JSON như một cái gì đó bắt đầu bằng một {ký tự. Đối với trường hợp mảng, miễn là bạn không cần hỗ trợ IE <9, bạn có thể sử dụng Array.isArray()để xác định xem có thứ gì đó là mảng không. Nó vượt qua tất cả các trường hợp thử nghiệm bạn cung cấp.
Kip

81

Tôi thích đơn giản là:

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

Nếu mục đó là một đối tượng JS và nó không phải là một mảng JS và nó không phải là nullnếu nếu cả ba đều chứng minh đúng, hãy trả về true. Nếu bất kỳ điều kiện nào trong ba điều kiện không thành công, &&thử nghiệm sẽ bị đoản mạch và falsesẽ được trả lại. Các nullthử nghiệm có thể được bỏ qua nếu muốn (tùy thuộc vào cách bạn sử dụng null).

TÀI LIỆU:

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

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

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

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


3
Còn console.log (isObject (ngày mới ())) thì sao? Tại sao một ngày nên là một đối tượng nhưng một mảng không?
schirrmacher

5
@macher Vì new Date()trả về một đối tượng. Một mảng là từ quan điểm logic không phải là một đối tượng - mặc dù JavaScript xử lý và báo cáo chúng như vậy. Trong thực tế, tuy nhiên, không hữu ích khi thấy chúng bằng nhau, bởi vì chúng không phải là. Một đối tượng không có lengththuộc tính chẳng hạn và nó không có các phương thức như push (). Và đôi khi bạn có thể muốn cung cấp một hàm bị quá tải, trong đó bạn cần tạo sự khác biệt giữa một mảng hoặc một đối tượng, đặc biệt nếu các tham số khác phụ thuộc vào cái nào được đưa ra.
StanE

1
@StanE Mảng chắc chắn là đối tượng. Không chắc chắn lý do tại sao bạn nghĩ các đối tượng không thể có một thuộc lengthtính cũng như các phương thức như push, Object.create(Array.prototype)là một ví dụ tầm thường của một đối tượng không có mảng có các đối tượng này. Điều làm cho mảng đặc biệt là chúng là các đối tượng kỳ lạ với một phương thức bên trong thiết yếu [[DefineOwnProperty]] tùy chỉnh, nhưng chúng vẫn là các đối tượng.
Oriol

4
@Oriol Tôi không viết rằng mảng không phải là đối tượng và tôi cũng không viết rằng các đối tượng không thể có thuộc lengthtính (ý tôi là các đối tượng theo nghĩa đen không có lengththuộc tính theo mặc định). Tôi đã viết rằng mảng không phải là đối tượng từ quan điểm logic . Tôi đang nói về logic chương trình. Đôi khi cần phải kiểm tra xem một mảng có phải là mảng "thực" hay không và chắc chắn không phải là một đối tượng "thực". Đó là những gì Array.isArray()dành cho. Hãy tưởng tượng bạn có một hàm chấp nhận một đối tượng hoặc một mảng các đối tượng. Kiểm tra một thuộc tính hoặc phương pháp đặc biệt là một giải pháp bẩn. Cách bản địa luôn tốt hơn.
StanE

2
typeof null"object", không "undefined".
2540625

80

Với chức năng Array.isArray:

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

Không có chức năng Array.isArray:

Chỉ ngạc nhiên có bao nhiêu upvote cho câu trả lời sai
Chỉ có 1 câu trả lời vượt qua bài kiểm tra của tôi !!! Ở đây tôi đã tạo phiên bản đơn giản hóa của mình:

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

Đối với tôi, nó rõ ràng và đơn giản, và chỉ hoạt động! Đây là bài kiểm tra của tôi:

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

MỘT THỜI GIAN HƠN: không phải tất cả các câu trả lời đều vượt qua bài kiểm tra này !!! 🙈


Trong trường hợp bạn cần xác minh đối tượng đó là thể hiện của lớp cụ thể, bạn phải kiểm tra hàm tạo với lớp cụ thể của mình, như:

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

kiểm tra đơn giản:

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

Kết quả là, bạn sẽ có mã nghiêm ngặt và mạnh mẽ!


Trong trường hợp bạn sẽ không tạo ra các chức năng như isDate, isError, isRegExp, vv bạn có thể cân nhắc lựa chọn để sử dụng chức năng tổng quát này:

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

nó sẽ không hoạt động chính xác cho tất cả các trường hợp thử nghiệm được đề cập trước đó, nhưng nó đủ tốt cho tất cả các đối tượng (đơn giản hoặc được xây dựng).


isObjectsẽ không hoạt động trong trường hợp Object.create(null)vì triển khai nội bộ Object.createđược giải thích ở đây nhưng bạn có thể sử dụng isObjecttrong triển khai tinh vi hơn:

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;
};

Đã có gói đã được tạo trên npm v1 dựa trên việc triển khai này! Và nó hoạt động cho tất cả các trường hợp thử nghiệm được mô tả trước đó! 🙂


câu trả lời tốt nhất! hoạt động cho nhiều trường hợp được đề cập ở đây
tiên tri

Bởi vì điều này trả về false cho isObject (myDateObject), đây không phải là câu trả lời cho câu hỏi. Nó không cho biết nếu một biến là một đối tượng, chỉ khi nó là một đối tượng của một lớp cụ thể. Câu hỏi ở đây là về một hàm chung trả về true cho bất kỳ đối tượng nào.
Yetanotherjosh

@Yetanotherjosh Đây thực sự là một câu trả lời bạn đã đề cập đến trường hợp được mô tả trong câu trả lời và vấn đề - bạn phải sử dụng isDatecho yourDateObject với mục đích viết mã mạnh nếu không bạn sẽ có isObjectphương pháp dễ vỡ .
V. Kovpak

@VladimirKovpak Sử dụng Datetrong nhận xét của tôi không được chọn vì có, câu trả lời sẽ thảo luận Date. Nhưng Datechỉ là một trong những lớp vô hạn có thể và điểm giữ cho bất kỳ lớp nào khác. Ví dụ: class Foo() { }; var x = new Foo(); isObject(x)trả về false. Tôi không biết chính xác trường hợp sử dụng của OP là gì, nhưng thật dễ dàng để hình dung ra các kịch bản trong đó phải biết về tất cả các lớp có thể và kiểm tra cụ thể đối với mọi trường hợp sẽ không khả thi.
Yetanotherjosh

@Yetanotherjosh Tôi đã cập nhật câu trả lời của mình. Và thêm 1 trường hợp nữa.
V. Kovpak

41

Ôi chúa ơi! Tôi nghĩ rằng điều này có thể ngắn hơn bao giờ hết, hãy xem điều này:

Mã ngắn và cuối cùng

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

Giải thích

Các loại trả về

loại đối tượng JavaScript (bao gồm null) trả về"object"

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

Kiểm tra các nhà xây dựng của họ

Kiểm tra constructorchức năng trả về tài sản của họ với tên của họ.

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

Giới thiệu Hàm.name

Function.nametrả về tên chỉ đọc của hàm hoặc "anonymous"cho các bao đóng.

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

Lưu ý: Kể từ năm 2018, Function.name có thể không hoạt động trong IE https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compabilities


3
Tôi thực sự thích cái này, ngắn và cho điểm. Nó chỉ thất bại ở 1 điều xa như tôi có thể thấy. if obj = Object.create(null)và khá tại sao bạn sẽ làm điều đó ...?
Julian Knight

29

OK, hãy cung cấp cho bạn khái niệm này đầu tiên trước khi trả lời câu hỏi của bạn, trong chức năng Javascript là Object, cũng null, Object, Mảng và thậm chí cả ngày, vì vậy khi bạn thấy có không một cách đơn giản như typeof obj === 'đối tượng', vì vậy mọi thứ được đề cập ở trên sẽ trả về đúng , nhưng có nhiều cách để kiểm tra nó bằng cách viết một hàm hoặc sử dụng các khung JavaScript, OK:

Bây giờ, hãy tưởng tượng bạn có đối tượng này là một đối tượng thực sự (không phải null hoặc hàm hoặc mảng):

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

JavaScript thuần túy:

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

hoặc là

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

hoặc là

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

hoặc là

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

Bạn chỉ có thể sử dụng một trong các hàm như trên trong mã của mình bằng cách gọi chúng và nó sẽ trả về đúng nếu đó là một đối tượng:

isObject(obj);

Nếu bạn đang sử dụng khung JavaScript, họ thường đã chuẩn bị các loại chức năng này cho bạn, đây là một số trong số chúng:

jQuery:

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

Góc cạnh:

angular.isObject(obj);

Gạch dưới và gạch ngang:

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

Bạn cũng muốn kiểm tra xem nó không phải là một mảng. vì vậy hàm isObject (obj) {return obj! == null && typeof obj === 'object' &&! Array.isArray (obj); }
Matt Goo

Tôi đồng ý với bạn, nhưng như bạn thấy trong phần bình luận, đó là cách nó được thực hiện trong angularJs và tôi đề cập đến nó trong phần bình luận trước hàm, họ coi Array là một đối tượng ... nhìn vào đây để biết thêm thông tin: docs .angularjs.org / api / ng / function / angular.isObject
Alireza

24

Nó phụ thuộc vào ý của bạn với "là một đối tượng". Nếu bạn muốn tất cả mọi thứ không phải là nguyên thủy , tức là những thứ mà bạn có thể thiết lập các thuộc tính mới, điều này sẽ thực hiện mẹo:

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

Nó không bao gồm các nguyên thủy (số đồng bằng / NaN/ Infinity, dây đồng bằng, ký hiệu, true/ false, undefinednull) nhưng phải trả lại đúng đối với mọi thứ khác (bao gồm cả Number, BooleanStringcác đối tượng). Lưu ý rằng JS không định nghĩa những đối tượng "máy chủ" nào, chẳng hạn như windowhoặc console, sẽ trả về khi được sử dụng cùng typeof, vì vậy những đối tượng này khó có thể kiểm tra bằng một kiểm tra như thế này.

Nếu bạn muốn biết liệu một cái gì đó là một đối tượng "đơn giản", tức là nó được tạo ra theo nghĩa đen {}hoặc với Object.create(null), bạn có thể làm điều này:

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;
    }
}

Chỉnh sửa 2018 : Vì Symbol.toStringTaghiện tại cho phép tùy chỉnh đầu ra của Object.prototype.toString.call(...), isPlainObjecthàm trên có thể trở lại falsetrong một số trường hợp ngay cả khi đối tượng bắt đầu cuộc sống như một nghĩa đen. Có thể cho rằng, bằng cách quy ước một đối tượng có thẻ chuỗi tùy chỉnh không còn chính xác là một đối tượng đơn giản nữa, nhưng điều này đã làm rối thêm định nghĩa về những gì một đối tượng đơn giản thậm chí là trong Javascript.


Tại sao typeof === 'function' được coi là một đối tượng? Một chức năng không phải là một đối tượng, phải không? "new myFunc ()" sẽ trở thành một đối tượng, vâng, nhưng là một hàm đơn giản?
StanE

Không, mọi chức năng là một đối tượng trong Javascript, bất kể nó được tạo như thế nào. Bạn có thể đặt các thuộc tính trên chúng (trừ khi chúng bị đóng băng), chúng là instanceof Object, hai chữ có chức năng giống hệt nhau không hoàn toàn bằng nhau, chúng được chuyển qua tham chiếu, v.v.
cuối

21

Chúa ơi, quá nhiều nhầm lẫn trong các câu trả lời khác.

Câu trả lời ngắn

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

Để kiểm tra điều này chỉ cần chạy các câu lệnh sau trong bảng điều khiển chrome.

Trường hợp 1.

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

Trường hợp 2.

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

Trường hợp 3.

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

Giải trình

Được rồi. Hãy phá vỡ nó

typeof anyVar == 'object'được trả lại đúng từ ba ứng cử viên - [], {} and null,

anyVar instanceof Object thu hẹp những ứng cử viên này xuống còn hai - [], {}

!(anyVar instanceof Array) thu hẹp chỉ còn một - {}

Trống cuộn vui lòng!

Bằng cách này, bạn có thể đã học cách kiểm tra Array trong Javascript.


2
Lưu ý, điều này cũng trả về false(như mong muốn) khi anyVarlà một hàm.
Jamie Birch

18

Cách hợp lý nhất để kiểm tra loại giá trị có vẻ như typeoftoán tử. Vấn đề duy nhất là nó bị hỏng khủng khiếp:

  • Nó sẽ trả về "object"cho null, mà thuộc về loại Null.
  • Nó trả về "function"cho các đối tượng có thể gọi được, thuộc loại Object.
  • Nó có thể trả về (gần như) bất cứ thứ gì nó muốn cho các đối tượng không thể gọi được không chuẩn. Ví dụ, IE có vẻ thích "unknown". Các kết quả bị cấm duy nhất là "function"và các loại nguyên thủy.

typeofchỉ đáng tin cậy cho người không nullnguyên thủy. Vì vậy, một cách để kiểm tra xem một giá trị có phải là một đối tượng hay không sẽ đảm bảo rằng chuỗi được trả về typeofkhông tương ứng với một nguyên thủy và đối tượng đó thì không null. Tuy nhiên, vấn đề là một tiêu chuẩn trong tương lai có thể giới thiệu một kiểu nguyên thủy mới và mã của chúng tôi sẽ coi nó là một đối tượng. Các loại mới không xuất hiện thường xuyên, nhưng ví dụ ECMAScript 6 đã giới thiệu loại Biểu tượng.

Do đó, thay vì typeof, tôi chỉ đề xuất các phương pháp tiếp cận có kết quả khác nhau tùy thuộc vào việc giá trị có phải là một đối tượng hay không. Sau đây dự định là một

Danh sách toàn diện nhưng không đầy đủ các cách thích hợp để kiểm tra nếu một giá trị thuộc về loại Đối tượng.

  • Object constructor

    Hàm Objecttạo cưỡng chế đối số đã truyền cho một đối tượng. Nếu nó đã là một đối tượng, cùng một đối tượng được trả về.

    Do đó, bạn có thể sử dụng nó để ép buộc giá trị cho một đối tượng và so sánh nghiêm ngặt đối tượng đó với giá trị ban đầu.

    Hàm sau yêu cầu ECMAScript 3, được giới thiệu ===:

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

    Tôi thích cách tiếp cận này vì nó đơn giản và tự mô tả, và một kiểm tra tương tự cũng sẽ hoạt động đối với booleans, số và chuỗi. Tuy nhiên, hãy lưu ý rằng nó dựa vào toàn cầu Objectkhông bị che khuất cũng không bị thay đổi.

  • Người xây dựng

    Khi bạn khởi tạo một hàm tạo, nó có thể trả về một giá trị khác với thể hiện vừa tạo. Nhưng giá trị đó sẽ bị bỏ qua trừ khi đó là một đối tượng.

    Hàm sau yêu cầu ECMAScript 3, cho phép các nhà xây dựng trả về các đối tượng không. Trước ECMAScript 3 đã phát sinh lỗi, nhưng các trycâu lệnh đã không tồn tại trước đó.

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

    Mặc dù đơn giản hơn một chút so với ví dụ trước, nhưng điều này không dựa vào bất kỳ tài sản toàn cầu nào, và do đó có thể là an toàn nhất.

  • this giá trị

    Thông số kỹ thuật ECMAScript cũ yêu cầu thisgiá trị phải là một đối tượng. ECMAScript 3 được giới thiệu Function.prototype.call, cho phép gọi một hàm có thisgiá trị tùy ý , nhưng bị ép buộc vào một đối tượng.

    ECMAScript 5 đã giới thiệu một chế độ nghiêm ngặt loại bỏ hành vi này, nhưng ở chế độ cẩu thả, chúng ta vẫn có thể (nhưng có thể không nên) dựa vào nó.

    function isObject(value) { /* Requires ECMAScript 3 or later in sloppy mode */
      return function() { return this === value; }.call(value);
    }
  • [[Nguyên mẫu]]

    Tất cả các đối tượng bình thường đều có một khe bên trong gọi là [[Prototype]], có giá trị xác định từ đối tượng khác mà nó thừa hưởng từ đó. Giá trị chỉ có thể là một đối tượng hoặc null. Do đó, bạn có thể cố gắng tạo một đối tượng kế thừa từ giá trị mong muốn và kiểm tra xem nó có hoạt động không.

    Cả hai Object.createObject.getPrototypeOfyêu cầu 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;
    }
  • Một số ECMAScript mới 6 cách

    ECMAScript 6 giới thiệu một số cách gián tiếp mới để kiểm tra giá trị là một đối tượng. Họ sử dụng cách tiếp cận đã thấy trước đó để chuyển giá trị cho một số mã yêu cầu một đối tượng, được bọc bên trong một trycâu lệnh để bắt lỗi. Một số ví dụ ẩn, không đáng để bình luận


Lưu ý: Tôi cố tình bỏ qua một số cách tiếp cận như Object.getPrototypeOf(value)(ES5) và Reflectphương thức (ES6) vì chúng gọi các phương thức nội bộ thiết yếu có thể làm những điều khó chịu, ví dụ nếu valuelà proxy. Vì lý do an toàn, ví dụ của tôi chỉ tham khảo valuemà không truy cập trực tiếp.


2
"Chỉ có câu trả lời của tôi và Daan là hoàn toàn chính xác." là một chút tự phụ cho rằng tôi hoàn toàn không đồng ý với hai câu đầu tiên của bạn.
zzzzBov

1
@zzzzBov Chà, tôi đã xem tất cả các câu trả lời và họ không đảm bảo luôn trả lời đúng câu trả lời, ngoại trừ của tôi và của Daan. Tôi có thể cung cấp các mẫu phản ứng có thể tái tạo cho hầu hết chúng. Những người khác khuyên bạn nên kiểm tra xem typeof trả về "hàm" hay "đối tượng", nhưng như tôi đã giải thích, thông số kỹ thuật cho phép các kết quả khác cho một số đối tượng. Câu trả lời của Matt Fenwick chứa câu trả lời đúng giống như của Daan, nhưng cũng chứa câu trả lời sai.
Oriol

1
Tôi không đồng ý với tiền đề rằng câu trả lời của bạn là "hoàn toàn chính xác", cho rằng người khác "không đảm bảo luôn trả lời đúng" không bác bỏ quan điểm của tôi theo bất kỳ cách nào. Ngoài ra, câu hỏi không đưa ra bất kỳ khiếu nại nào liên quan đến đầu vào nào sẽ tạo ra đầu ra nào.
zzzzBov

1
@zzzzBov Câu hỏi hỏi làm thế nào để kiểm tra nếu một cái gì đó là một đối tượng. ECMAScript định nghĩa đối tượng là gì, vì vậy tôi sử dụng định nghĩa đó. Tôi không thể thấy bất kỳ giải thích hợp lý khác. Câu trả lời làm những việc khác (như loại trừ mảng) có thể hữu ích trong một số trường hợp, nhưng họ không kiểm tra xem có thứ gì đó là một đối tượng không.
Oriol


15

Thử cái này

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

14
Tại sao bạn dobule kiểm tra booleans?
jkutianski

5
Điều này bỏ lỡ hai trường hợp: Object.prototype instanceof Object-> sai. Object.create(null) instanceof Object-> sai.
Matt Fenwick

ngày tháng thì sao? new Date() instanceof Object => đúng
mauron85

13

Sẵn sàng sử dụng các chức năng để kiểm tra

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

Giải trình

  • Trong Javascript, null, Object, Array, Datefunctions là tất cả các đối tượng. Mặc dù, nulllà một chút giả định. Vì vậy, tốt hơn hết là kiểm tra nulllần đầu tiên, để phát hiện ra nó không phải là null.

  • Kiểm tra để typeof o === 'object'đảm bảo đó olà một đối tượng. Nếu không có kiểm tra này, Object.prototype.toStringsẽ là vô nghĩa, vì nó sẽ trả lại đối tượng cho mọi thứ, ngay cả cho undefinednull! Ví dụ: toString(undefined)trả về [object Undefined]!

    Sau khi typeof o === 'object'kiểm tra, toString.call (o) là một phương pháp tuyệt vời để kiểm tra xem olà một đối tượng, một đối tượng có nguồn gốc như Array, Datehoặc một function.

  • Trong isDerivedObjectchức năng, nó kiểm tra cho olà một chức năng. Bởi vì, chức năng cũng là một đối tượng, đó là lý do tại sao nó ở đó. Nếu nó không làm điều đó, chức năng sẽ trở lại là sai. Ví dụ: isDerivedObject(function() {})sẽ trả về false, tuy nhiên bây giờ nó trả về true.

  • Người ta luôn có thể thay đổi định nghĩa về một đối tượng. Vì vậy, người ta có thể thay đổi các chức năng này cho phù hợp.


Xét nghiệm

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

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

// TESTS

// is null an object?

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

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

// is 1234 an object?

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

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

// is new Number(1234) an object?

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

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

// is function object an object?

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

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

// is {} an object?

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

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

// is Array an object?

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

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

// is Date an object?

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

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

// is function an object?

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

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


13

Nếu bạn muốn kiểm tra nếu chỉ prototypecho một objectđến từ Object. Lọc ra String, Number, Array, Argumentsvv

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

Hoặc là một hàm mũi tên biểu thức đơn (ES6 +)

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

1
đây là cách tốt nhất nhưng tôi sẽ làm cho nó dễ dàng hơn nữa trên dòng thứ 2:return Object.prototype.toString.call(n) === '[object Object]'
mesqueeb

1
Bạn cũng có thể xóa nullséc, bởi vìObject.prototype.toString.call(null) === '[object Null]'
Gust van de Wal

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

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

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

Tôi đã được yêu cầu cung cấp thêm chi tiết. Cách kiểm tra rõ ràng và dễ hiểu nhất nếu biến của chúng ta là một đối tượng typeof myVar. Nó trả về một chuỗi với một loại (ví dụ "object", "undefined").

Thật không may, Array và null cũng có một loại object. Để chỉ lấy các đối tượng thực, cần phải kiểm tra chuỗi thừa kế bằng instanceoftoán tử. Nó sẽ loại bỏ null, nhưng Array có Object trong chuỗi thừa kế.

Vì vậy, giải pháp là:

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

/./ instanceof Object //true
yckart

11

Hơi muộn ... đối với "các đối tượng đơn giản" (ý tôi là, như {'x': 5, 'y': 7}) tôi có đoạn trích nhỏ này:

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

Nó tạo ra đầu ra tiếp theo:

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

Nó luôn làm việc cho tôi. Nếu sẽ trả về "true" chỉ khi loại "o" là "object", nhưng không có null, hoặc mảng hoặc hàm. :)


Như đã đề cập trong các câu trả lời trước, cách tiếp cận của bạn sẽ thất bại trong trường hợp đối tượng Date.
Grzegorz Pawlik

9

lodash có isPlainObject , có thể là điều mà nhiều người đến trang này đang tìm kiếm. Nó trả về false khi đưa ra một hàm hoặc mảng.


Hoàn hảo! Tôi biết về _.isObjectnhững gì phù hợp với những gì JS coi là một đối tượng. Nhưng những gì tôi thường cần là phân biệt giữa ví dụ một đối tượng theo nghĩa đen và một mảng, đó chính xác là những gì _.isPlainObjectcho phép tôi làm.
vôi

9

Điều này sẽ làm việc. Đây là một hàm trả về true, false hoặc có thể 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


2
@SeregPie Trong tương lai, bạn không nên chỉnh sửa mã trong câu trả lời. Như câu trả lời này, khi kiểm tra tôi đã đạt được nullkết quả cho bài kiểm tra cuối cùng chứ không phải false. Xem Khi nào tôi nên chỉnh sửa mã?
Nick

9

Vì có vẻ có nhiều nhầm lẫn về cách xử lý vấn đề này một cách chính xác, tôi sẽ để lại 2 xu của mình (câu trả lời này tuân thủ thông số kỹ thuật và tạo ra kết quả chính xác trong mọi trường hợp):

Kiểm tra nguyên thủy: undefined null boolean string number

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

Một đối tượng không phải là nguyên thủy:

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

Hay cách khác:

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

Kiểm tra bất kỳ mảng nào:

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

Kiểm tra đối tượng không bao gồm: Date RegExp Boolean Number String Functionbất kỳ Mảng

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

8

Khi mọi thứ khác thất bại, tôi sử dụng điều này:

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

1
Tại sao so sánh chuỗi, tại sao không đơn giản item.constructor === Object?
K3 --- rnc

nullném một ngoại lệUncaught TypeError: Cannot read property 'constructor' of null(…)
Vitim.us

@rounce Tôi đang hướng tới hỗ trợ các phiên bản IE cũ hơn, tại sao nó không hoạt động trong IE? Vì indexOfhay vì constructor.name?
Jankapunkt

8

Các Ramda thư viện chức năng có một chức năng tuyệt vời cho việc phát hiện loại JavaScript.

Diễn giải đầy đủ chức năng :

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

Tôi đã phải bật cười khi nhận ra giải pháp đơn giản và đẹp đẽ biết bao.

Ví dụ sử dụng từ tài liệu 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"

8

Sau khi đọc và cố gắng ra rất nhiều hiện thực, tôi đã nhận thấy rằng rất ít người cố gắng để kiểm tra giá trị như JSON, Math, documenthoặc đối tượng với chuỗi nguyên mẫu dài hơn 1 bước.

Thay vì kiểm tra typeofbiến của chúng tôi và sau đó hack các trường hợp cạnh, tôi nghĩ sẽ tốt hơn nếu kiểm tra được giữ đơn giản nhất có thể để tránh phải cấu trúc lại khi có các đối tượng nguyên thủy hoặc đối tượng gốc mới được đăng ký như là typeofđối tượng '.

Rốt cuộc, typeoftoán tử sẽ cho bạn biết nếu một cái gì đó là một đối tượng với JavaScript , nhưng định nghĩa về một đối tượng của JavaScript quá rộng đối với hầu hết các kịch bản trong thế giới thực (ví dụ typeof null === 'object'). Dưới đây là một hàm xác định xem biến có phải vlà một đối tượng hay không bằng cách lặp lại hai lần kiểm tra:

  1. Một vòng lặp được bắt đầu tiếp tục miễn là phiên bản được xâu chuỗi v'[object Object]'.
    Tôi muốn kết quả của hàm giống hệt như các bản ghi bên dưới, vì vậy đây là "tiêu chí" duy nhất mà tôi đã kết thúc. Nếu thất bại, hàm trả về false ngay lập tức.
  2. vđược thay thế bằng nguyên mẫu tiếp theo trong chuỗi với v = Object.getPrototypeOf(v), nhưng cũng được đánh giá trực tiếp sau đó. Khi giá trị mới vnull, điều đó có nghĩa là mọi nguyên mẫu bao gồm nguyên mẫu gốc (rất có thể là nguyên mẫu duy nhất trong chuỗi) đã vượt qua kiểm tra trong vòng lặp while và chúng ta có thể trả về giá trị true. Nếu không, một lần lặp mới bắt đầu.

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

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

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


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

1
Nếu valuenullđiều này sẽ ném ra một lỗi ...
Gershom

Và tất nhiên nó sẽ falsedành cho đối tượng Object.assign({}, {constructor: null}).
dùng4642212

6

Nếu rõ ràng muốn kiểm tra nếu giá trị đã cho là {}.

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

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

!!objlà cách viết tắt để kiểm tra xem objcó đúng không (để lọc ra null)


6

Đó là một câu hỏi cũ nhưng nghĩ rằng để lại ở đây. Hầu hết mọi người đang kiểm tra xem biến đó có {}nghĩa là một cặp giá trị khóa hay không và cấu trúc gạch chân mà JavaScript đang sử dụng cho một thứ nhất định là gì, vì thành thật mà nói, hầu hết mọi thứ trong JavaScript đều là một đối tượng. Vì vậy, đưa nó ra khỏi đường đi. Nếu bạn làm...

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

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

Hầu hết thời gian những gì chúng ta muốn là để biết liệu chúng ta có một đối tượng tài nguyên từ API hoặc cuộc gọi cơ sở dữ liệu của chúng ta được trả về từ ORM hay không. Sau đó chúng ta có thể kiểm tra nếu không phải là Array, không phải null, không phải 'function'là loại và làObject

// 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

bật truechonew Date()
chập chững

1
@toddmo cảm ơn bạn đã chỉ ra điều đó. Bây giờ mã ví dụ trả về false chonew Date()
Gilbert

4

Những gì tôi thích sử dụng là này

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

Tôi nghĩ rằng trong hầu hết các trường hợp, Ngày phải vượt qua kiểm tra dưới dạng Đối tượng, vì vậy tôi không lọc ngày hết


4

tôi đã tìm thấy một cách "mới" để thực hiện loại kiểm tra kiểu này từ câu hỏi SO này: Tại sao instanceof trả về false cho một số chữ?

từ đó, tôi đã tạo một hàm để kiểm tra kiểu như sau:

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

sau đó bạn có thể làm

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

điều này đã được thử nghiệm trên Chrome 56, Firefox 52, Microsoft Edge 38, Internet Explorer 11, Opera 43

chỉnh sửa:
nếu bạn cũng muốn kiểm tra xem một biến là null hoặc không xác định, bạn có thể sử dụng thay thế này:

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

cập nhật từ bình luận của inanc: thách thức được chấp nhận: D

Nếu bạn muốn thả lỏng so sánh các đối tượng, bạn có thể thử theo cách này:

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
        }
    }
}

Bằng cách đó, bạn có thể làm giống như bình luận của inanc:

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

hoặc là

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

Điều này không thể phát hiện xem một lớp mới là một đối tượng. isVarTypeOf (new (function Foo () {}), Object) // Điều này trả về false thay vì true. Xem câu trả lời của tôi dưới đây để kiểm tra thích hợp.
Inanc Gumus

Tuy nhiên, bạn có thể sử dụng instanceofđể kiểm tra các đối tượng. Tuy nhiên, đây không phải là một khoa học chính xác.
Inanc Gumus

@inanc, cũng có nghĩa là vì new Foo()lợi nhuận một Foođối tượng, giống như new String()trở về một Stringđối tượng, hoặc new Date()trả về một Dateđối tượng, bạn có thể làm Foo = function(){}; isVarTypeOf(new Foo(), Foo);cũng
am05mhz

Vâng, đó là những gì tôi nói thực sự: Bạn không kiểm tra xem đó có phải là một đối tượng ngay bây giờ không.
Inanc Gumus

@inanc Chúc mừng, tôi đang tìm cách để kiểm tra loại (không chỉ đối tượng), đã đến trang này và trang kia, sau đó tôi đã quá phấn khích vì tôi quên mất bối cảnh của câu hỏi này, xấu của tôi :)
am05mhz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.