Làm cách nào để kiểm tra xem giá trị có phải là Đối tượng trong JavaScript không?
Làm cách nào để kiểm tra xem giá trị có phải là Đối tượng trong JavaScript không?
Câu trả lời:
CẬP NHẬT :
Câu trả lời này không đầy đủ và cho kết quả sai lệch . Ví dụ, null
cũng được xem là loại object
trong 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!).
typeof
là một nhà điều hành, vì vậy không cần ()
.
typeof
trả về 'đối tượng' cho null, không phải là một đối tượng và instanceof
khô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)
.
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
.
yourVariable !== null
được thực hành tốt hơn?
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.
typeof
vì 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
.
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]
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
Object.prototype
Function.prototype
Object
Function
function C(){}
- các hàm do người dùng định nghĩaC.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 địnhMath
Array.prototype
{"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ủyObject.create(null)
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({})
obj === Object(obj)
trả về true
cho mảng.
var x = []; console.log(x === Object(x)); // return true
getPrototypeOf
khô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.
({}).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
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;
};
return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
null
, quá. Nên là câu trả lời được chấp nhận.
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Để 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 .
typeof [] === 'object'
-> true
. Đó là những gì bạn cần phương pháp này.
Object.prototype.toString.call(3)
-> "[object Number]"
. Object.prototype.toString.call(new Number(3))
-> "[object Number]
"
getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
Để 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
isObject
chỉ 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
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 )!
{
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.
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à null
nế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à false
sẽ được trả lại. Các null
thử 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
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ó length
thuộ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.
length
tí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.
length
tính (ý tôi là các đối tượng theo nghĩa đen không có length
thuộ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.
typeof null
là "object"
, không "undefined"
.
Array.isArray
:function isObject(o) {
return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}
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).
isObject
sẽ 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 isObject
trong 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 đó! 🙂
isDate
cho yourDateObject với mục đích viết mã mạnh nếu không bạn sẽ có isObject
phương pháp dễ vỡ .
Date
trong 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 Date
chỉ 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.
Ô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:
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
loại đối tượng JavaScript (bao gồm null
) trả về"object"
console.log(typeof null, typeof [], typeof {})
Kiểm tra constructor
chứ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
Function.name
trả 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
Object.create(null)
và khá tại sao bạn sẽ làm điều đó ...?
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);
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
, undefined
và null
) nhưng phải trả lại đúng đối với mọi thứ khác (bao gồm cả Number
, Boolean
và String
cá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ư window
hoặ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.toStringTag
hiện tại cho phép tùy chỉnh đầu ra của Object.prototype.toString.call(...)
, isPlainObject
hàm trên có thể trở lại false
trong 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.
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.
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.
false
(như mong muốn) khi anyVar
là một hàm.
Cách hợp lý nhất để kiểm tra loại giá trị có vẻ như typeof
toán tử. Vấn đề duy nhất là nó bị hỏng khủng khiếp:
"object"
cho null
, mà thuộc về loại Null."function"
cho các đối tượng có thể gọi được, thuộc loại Object."unknown"
. Các kết quả bị cấm duy nhất là "function"
và các loại nguyên thủy.typeof
chỉ đáng tin cậy cho người không null
nguyê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ề typeof
khô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
Object
constructor
Hàm Object
tạ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 Object
khô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 try
câ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 this
giá 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ó this
giá 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.create
và Object.getPrototypeOf
yê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 try
câ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à Reflect
phươ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 value
là proxy. Vì lý do an toàn, ví dụ của tôi chỉ tham khảo value
mà không truy cập trực tiếp.
Thử cái này
if (objectName instanceof Object == false) {
alert('Not an object');
}
else {
alert('An object');
}
Object.prototype instanceof Object
-> sai. Object.create(null) instanceof Object
-> sai.
new Date() instanceof Object
=> đúng
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
Trong Javascript, null
, Object
, Array
, Date
và function
s là tất cả các đối tượng. Mặc dù, null
là một chút giả định. Vì vậy, tốt hơn hết là kiểm tra null
lầ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 đó o
là một đối tượng. Nếu không có kiểm tra này, Object.prototype.toString
sẽ là vô nghĩa, vì nó sẽ trả lại đối tượng cho mọi thứ, ngay cả cho undefined
và null
! 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 o
là một đối tượng, một đối tượng có nguồn gốc như Array
, Date
hoặc một function
.
Trong isDerivedObject
chức năng, nó kiểm tra cho o
là 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.
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(){})
);
Nếu bạn muốn kiểm tra nếu chỉ prototype
cho một object
đến từ Object
. Lọc ra String
, Number
, Array
, Arguments
vv
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]'
return Object.prototype.toString.call(n) === '[object Object]'
null
séc, bởi vìObject.prototype.toString.call(null) === '[object Null]'
var a = [1]
typeof a //"object"
a instanceof Object //true
a instanceof Array //true
var b ={a: 1}
b instanceof Object //true
b instanceof Array //false
var c = null
c instanceof Object //false
c instanceof Array //false
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 instanceof
toá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
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. :)
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.
_.isObject
nhữ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ì _.isPlainObject
cho phép tôi làm.
Đ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
null
kế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ã?
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
Function
bấ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];
}
}());
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";
};
item.constructor === Object
?
null
ném một ngoại lệUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
hay vì constructor.name
?
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"
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
, document
hoặc đối tượng với chuỗi nguyên mẫu dài hơn 1 bước.
Thay vì kiểm tra typeof
biế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, typeof
toá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 v
là một đối tượng hay không bằng cách lặp lại hai lần kiểm tra:
v
là '[object Object]'
. 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 v
là null
, đ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'}))))
if(typeof value === 'object' && value.constructor === Object)
{
console.log("This is an object");
}
value
là null
điều này sẽ ném ra một lỗi ...
false
dành cho đối tượng Object.assign({}, {constructor: null})
.
Đó 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
true
chonew Date()
new Date()
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
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
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.
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
null
là một đối tượng) hay không.