Làm cách nào để kiểm tra xem đối tượng có thuộc tính nào trong JavaScript không?


167

Giả sử tôi tuyên bố

var ad = {}; 

Làm cách nào để kiểm tra xem đối tượng này có chứa bất kỳ thuộc tính nào do người dùng xác định không?

Câu trả lời:


86

Bạn có thể lặp qua các thuộc tính của đối tượng của bạn như sau:

for(var prop in ad) {
    if (ad.hasOwnProperty(prop)) {
        // handle prop as required
    }
}

Điều quan trọng là sử dụng hasOwnProperty()phương thức, để xác định xem đối tượng có thuộc tính được chỉ định làm thuộc tính trực tiếp hay không và không được kế thừa từ chuỗi nguyên mẫu của đối tượng.

Biên tập

Từ các bình luận: Bạn có thể đặt mã đó vào một hàm và làm cho nó trả về sai ngay khi nó đến phần có bình luận

Kiểm tra hiệu suất

Test Of Object.Keys vs For..In Khi kiểm tra bất kỳ thuộc tính nào


2
Xin chào Daniel, thực ra tôi đang tìm kiếm một thiết bị để kiểm tra xem một đối tượng có chứa các đặc tính do người dùng định nghĩa hay không. Không kiểm tra xem một tài sản cụ thể tồn tại.
Ricky

7
@Ricky: Bạn có thể đặt mã đó vào một hàm và làm cho nó trả về sai ngay khi nó đến phần có bình luận.
Daniel Vassallo

8
Tôi nghĩ rằng những ngày này sử dụng Object.keyssẽ dễ dàng nhất: var a = [1,2,3];a.something=4;console.log(Object.keys(a))Bởi vì nó đã là một phần của ECMA 5, bạn có thể bắt đầu một cách an toàn: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
trộm

2
Lưu ý rằng "những ngày này" với ES5, các đối tượng gốc có thể có các thuộc tính riêng không đếm được, ví dụ Object.defineProperty(obj, 'foo', {enumerable:false, value:'foo'}).
RobG

2
Giải pháp này là một cách để kiểm tra các khóa tồn tại , nhưng câu trả lời đúng, hiệu quả và chính xác nhất nằm bên dưới bằng Object.keys (x) .length. Bạn không cần phải thực hiện chức năng của riêng mình, một chức năng đã tồn tại!
dudewad

192

Bạn có thể sử dụng Object.keysphương thức dựng sẵn để lấy danh sách các khóa trên một đối tượng và kiểm tra độ dài của nó.

var x = {};
// some code where value of x changes and than you want to check whether it is null or some object with values

if(Object.keys(x).length > 0){
 // Your code here if x has some properties  
}

13
Điều này đúng ở đây là câu trả lời chính xác. Câu trả lời được chấp nhận ở trên là một cách giải quyết và tốn kém hơn là chỉ kiểm tra số lượng khóa; Điều này làm cho cách có ý nghĩa hơn .
dudewad

6
Object.keys ("bí ẩn"); mang lại chìa khóa cũng như tôi nghĩ là không mong muốn. Câu trả lời này là không đầy đủ theo ý kiến ​​của tôi.
Mike de Klerk

2
@MikedeKlerk vui lòng đọc kỹ, không phải Object.keys ("bí ẩn"); đó là Object.keys (objectVariableName) sẽ trả về mảng của tất cả các khóa trong đối tượng. ví dụ: {'x': 'abc', 'y': 'def'} nó sẽ là ['x', 'y']
Dhaval Chaudhary

3
@DhavalChaudhary Cảm ơn bạn đã trả lời bình luận của tôi. Khi tôi thử mã này var str = "MyString"; Object.keys(str);, bàn điều khiển xuất ra 8 phím, từ 0 đến 7, cho mỗi ký tự. Hay tôi vẫn chưa hiểu câu trả lời.
Mike de Klerk

6
@MikedeKlerk nhưng đó chỉ là giải pháp cho các đối tượng không dành cho chuỗi, vui lòng tham khảo câu hỏi.
Dhaval Chaudhary

111

Điều gì về việc thực hiện một chức năng đơn giản?

function isEmptyObject(obj) {
  for(var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }
  }
  return true;
}

isEmptyObject({}); // true
isEmptyObject({foo:'bar'});  // false

Các hasOwnProperty gọi phương thức trực tiếp trên Object.prototypechỉ để thêm chút an toàn , hãy tưởng tượng như sau bằng cách sử dụng một obj.hasOwnProperty(...)cuộc gọi bình thường :

isEmptyObject({hasOwnProperty:'boom'});  // false

Lưu ý: (cho tương lai) Phương pháp trên chỉ dựa vào for...incâu lệnh và câu lệnh này chỉ lặp lại trên các thuộc tính có thể đếm được , trong Tiêu chuẩn ECMAScript được triển khai rộng rãi nhất (phiên bản thứ 3) mà lập trình viên không có cách nào để tạo ra các thuộc tính không thể đếm được .

Tuy nhiên, điều này đã thay đổi ngay bây giờ với ECMAScript Phiên bản thứ 5 và chúng tôi có thể tạo các thuộc tính không thể đếm được, không thể ghi hoặc không xóa được, vì vậy phương pháp trên có thể thất bại , ví dụ:

var obj = {};
Object.defineProperty(obj, 'test', { value: 'testVal', 
  enumerable: false,
  writable: true,
  configurable: true
});
isEmptyObject(obj); // true, wrong!!
obj.hasOwnProperty('test'); // true, the property exist!!

Một giải pháp ECMAScript 5 cho vấn đề này sẽ là:

function isEmptyObject(obj) {
  return Object.getOwnPropertyNames(obj).length === 0;
}

Các Object.getOwnPropertyNamestrở về phương pháp một Arraychứa tên của tất cả các đặc tính riêng của một đối tượng, đếm được hay không , phương pháp này đang được thực hiện tại bởi các nhà cung cấp trình duyệt, nó đã có trên 5 Beta Chrome và mới nhất WebKit đêm xây dựng.

Object.defineProperty cũng có sẵn trên các trình duyệt và các bản phát hành Firefox 3.7 Alpha mới nhất.


1
Lợi thế của Object.prototype.hasOwnProperty.call (obj, prop) so với obj.hasOwnProperty (prop) là gì?
Casey Chu

3
@Casey, đã được chỉnh sửa, nếu một đối tượng ghi đè lên thuộc hasOwnPropertytính, chức năng có thể bị sập ... Tôi biết tôi hơi hoang tưởng ... nhưng đôi khi bạn không biết mã của mình sẽ được sử dụng trong loại môi trường nào, nhưng bạn biết phương pháp nào bạn muốn sử dụng ...
CMS

2
+1 để trả lời câu hỏi này ... và các câu hỏi khác trong tương lai! :)
Daniel Vassallo

1
Lưu ý rằng cũng có một lỗi trong IE khi bạn có một thuộc tính có tên khớp với thuộc tính không thể đếm được trong Object.prototypeđó, thì nó không được liệt kê theo for...in. Vậy isEmptyObject({toString:1})sẽ thất bại. Đây là một trong những lý do không may bạn không thể hoàn toàn sử dụng Objectnhư một ánh xạ có mục đích chung.
bobince

1
@ MichaelMartin-Smucker- phím chỉ trả lại tài sản riêng đếm được, vì vậy không thích hợp ở đây.
RobG

58

Với jQuery bạn có thể sử dụng:

$.isEmptyObject(obj); // Returns: Boolean

Kể từ jQuery 1.4, phương thức này kiểm tra cả hai thuộc tính trên chính đối tượng và các thuộc tính được kế thừa từ các nguyên mẫu (trong đó nó không sử dụng hasOwnProperty).

Với ECMAScript Phiên bản thứ 5 trong các trình duyệt hiện đại (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +), bạn có thể sử dụng phương thức Object.keys tích hợp :

var obj = { blah: 1 };
var isEmpty = !Object.keys(obj).length;

Hoặc JavaScript cũ đơn giản:

var isEmpty = function(obj) {
               for(var p in obj){
                  return false;
               }
               return true;
            };


13

Nếu bạn đang sử dụng underscore.js thì bạn có thể sử dụng hàm _.isEmpty :

var obj = {};
var emptyObject = _.isEmpty(obj);

1
Chỉ cần cho bất kỳ ai đi ngang qua, đây không phải là một phương pháp dành riêng cho các đối tượng. _.isEmpty([]) // true Hãy chắc chắn kiểm tra trước: stackoverflow.com/a/22482737/1922747
djv

11

Nếu bạn sẵn sàng sử dụng lodash , bạn có thể sử dụng somephương pháp này.

_.some(obj) // returns true or false

Xem ví dụ jsbin nhỏ này


var x = [1,2] // true
djv

@damionjn Tôi đã thêm mã của bạn vào ví dụ. Tôi thấy quan điểm của bạn với mảng trả về câu trả lời sai, nhưng OP ban đầu đã khai báo một biến là một đối tượng nên tôi tin rằng nó ổn khi giả định điều này. Có một câu trả lời ở trên sử dụng phương thức isEmpty gạch dưới (lodash có cùng phương thức). Câu trả lời đó có cùng một vấn đề. Nếu bạn cung cấp cho isEmpty một mảng không trống, bạn cũng sẽ nhận được kết quả sai.
sfs

Đủ công bằng, nhưng chúng ta nên cung cấp câu trả lời với tất cả các cơ sở được bảo hiểm để chắc chắn thực hành tốt nhất. Bạn nói đúng, tôi đã vượt qua câu trả lời của anh ấy mà không có bất kỳ lời chỉ trích nào. Chỉ cần cho bất kỳ ai đi ngang qua, đây không phải là một phương pháp dành riêng cho các đối tượng. _.some([1, 2]) // true Hãy chắc chắn kiểm tra trước: stackoverflow.com/a/13356338/1922747
djv

5
for (var hasProperties in ad) break;
if (hasProperties)
    ... // ad has properties

Nếu bạn phải an toàn và kiểm tra các nguyên mẫu Object (chúng được thêm bởi một số thư viện nhất định và không có ở đó theo mặc định):

var hasProperties = false;
for (var x in ad) {
    if (ad.hasOwnProperty(x)) {
        hasProperties = true;
        break;
    }
}
if (hasProperties)
    ... // ad has properties

1
trong giải pháp của bạn không có bộ lọc cho các thuộc tính nguyên mẫu không mong muốn, điều đó có nghĩa là nó có thể hoạt động sai khi sử dụng thư viện như Prototype.js hoặc người dùng chưa có kinh nghiệm đã thêm các thuộc tính nguyên mẫu bổ sung vào đối tượng. Kiểm tra giải pháp Daniels trên trang này.
Joscha

Bạn không phải sử dụng thư viện hoặc chưa có kinh nghiệm để mở rộng nguyên mẫu của đối tượng. Một số lập trình viên có kinh nghiệm làm điều này tất cả các thời gian.
Alsciende

2
for(var memberName in ad)
{
  //Member Name: memberName
  //Member Value: ad[memberName]
}

Thành viên có nghĩa là tài sản thành viên, biến thành viên, bất cứ điều gì bạn muốn gọi nó> _>

Đoạn mã trên sẽ trả về MỌI THỨ, bao gồm cả toString ... Nếu bạn chỉ muốn xem liệu nguyên mẫu của đối tượng đã được mở rộng chưa:

var dummyObj = {};  
for(var memberName in ad)
{
  if(typeof(dummyObj[memberName]) == typeof(ad[memberName])) continue; //note A
  //Member Name: memberName
  //Member Value: ad[memberName]

}

Lưu ý A: Chúng tôi kiểm tra xem liệu thành viên của đối tượng giả có cùng loại với thành viên của đối tượng thử nghiệm của chúng tôi không. Nếu là phần mở rộng, loại thành viên của dummyobject phải là "không xác định"


Xin chào, tôi có thể biết liệu một đối tượng có chứa các thuộc tính hay không? Cảm ơn
Ricky

trong giải pháp của bạn không có bộ lọc cho các thuộc tính nguyên mẫu không mong muốn, điều đó có nghĩa là nó có thể hoạt động sai khi sử dụng thư viện như Prototype.js hoặc người dùng chưa có kinh nghiệm đã thêm các thuộc tính nguyên mẫu bổ sung vào đối tượng.
Joscha

kiểm tra giải pháp của Daniels trên trang này - nó ít bị lỗi hơn!
Joscha

2
Khối mã đầu tiên của bạn hoàn toàn không bao gồm nó. mã thứ hai chặn sai hoạt động nếu tôi thêm một biến vào đối tượng "quảng cáo" không xác định. Thực sự, hãy xem câu trả lời của Daniels, đây là cách duy nhất đúng và nhanh, vì nó sử dụng một triển khai riêng có tên là "hasOwnProperty".
Joscha

@Ricky: Nếu bạn muốn kiểm tra xem một đối tượng có chứa các thuộc tính hay không, bạn chỉ cần sử dụng ví dụ trong câu trả lời của tôi: stackoverflow.com/questions/2673121/ . Nếu mã đạt được bình luận, đối tượng của bạn sẽ không có bất kỳ thuộc tính trực tiếp nào. Nếu không, nó sẽ.
Daniel Vassallo

2
var hasAnyProps = false; for (var key in obj) { hasAnyProps = true; break; }
// as of this line hasAnyProps will show Boolean whether or not any iterable props exist

Đơn giản, hoạt động trong mọi trình duyệt và mặc dù về mặt kỹ thuật đó là một vòng lặp cho tất cả các khóa trên đối tượng, nó KHÔNG lặp qua tất cả ... hoặc là 0 và vòng lặp không chạy hoặc có một số và nó bị hỏng sau lần đầu tiên một (vì tất cả chúng ta đang kiểm tra là nếu có BẤT CỨ ... vậy tại sao lại tiếp tục?)


1

Câu trả lời rất muộn, nhưng đây là cách bạn có thể xử lý nó với các nguyên mẫu.

Array.prototype.Any = function(func) {
    return this.some(func || function(x) { return x });
}

Object.prototype.IsAny = function() {
    return Object.keys(this).Any();
}

0

Khi chắc chắn rằng đối tượng là đối tượng do người dùng xác định, cách dễ nhất để xác định xem UDO có trống không, sẽ là đoạn mã sau:

isEmpty=
/*b.b Troy III p.a.e*/
function(x,p){for(p in x)return!1;return!0};

Mặc dù phương pháp này (về bản chất) là một phương pháp suy diễn, - nó nhanh nhất và nhanh nhất có thể.

a={};
isEmpty(a) >> true

a.b=1
isEmpty(a) >> false 

ps :! không sử dụng nó trên các đối tượng do trình duyệt xác định.


... Trả về 0; trả lại 1}; sẽ giống nhau chứ?
phổ biến

1
@pike no, return! 1; return! 0 giống như return false; return true
Barshe

0

Trả lời muộn, nhưng một số khung xử lý các đối tượng là liệt kê. Do đó, bob.js có thể làm điều đó như thế này:

var objToTest = {};
var propertyCount = bob.collections.extend(objToTest).count();

0

Bạn có thể sử dụng như sau:

Đôi bang !! tra cứu tài sản

var a = !![]; // true
var a = !!null; // false

hasOwnProperty Đây là thứ mà tôi đã từng sử dụng:

var myObject = {
  name: 'John',
  address: null
};
if (myObject.hasOwnProperty('address')) { // true
  // do something if it exists.
}

Tuy nhiên, JavaScript đã quyết định không bảo vệ tên của phương thức, vì vậy nó có thể bị giả mạo.

var myObject = {
  hasOwnProperty: 'I will populate it myself!'
};

chống đỡ trong myObject

var myObject = {
  name: 'John',
  address: null,
  developer: false
};
'developer' in myObject; // true, remember it's looking for exists, not value.

loại

if (typeof myObject.name !== 'undefined') {
  // do something
}

Tuy nhiên, nó không kiểm tra null.

Tôi nghĩ rằng đây là cách tốt nhất.

trong nhà điều hành

var myObject = {
  name: 'John',
  address: null
};

if('name' in myObject) {
  console.log("Name exists in myObject");
}else{
  console.log("Name does not exist in myObject");
}

kết quả:

Tên tồn tại trong myObject

Đây là một liên kết đi sâu vào chi tiết hơn về toán tử trong: Xác định nếu một thuộc tính đối tượng tồn tại


0

Chức năng ES6

/**
 * Returns true if an object is empty.
 * @param  {*} obj the object to test
 * @return {boolean} returns true if object is empty, otherwise returns false
 */
const pureObjectIsEmpty = obj => obj && obj.constructor === Object && Object.keys(obj).length === 0

Ví dụ:


let obj = "this is an object with String constructor"
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {}
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = []
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = [{prop:"value"}]
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {prop:"value"}
console.log(pureObjectIsEmpty(obj)) // empty? false

-1

Còn cái này thì sao?

var obj = {},
var isEmpty = !obj;
var hasContent = !!obj

Câu trả lời này không trả lời câu hỏi. OP đang hỏi xem một đối tượng có chứa các thuộc tính do người dùng định nghĩa hay không - câu trả lời của bạn sẽ kiểm tra xem chính đối tượng đó có chuyển đổi thành giá trị sai Boolean hay không.
Jasmonate

... Và sau đó tôi cũng nhận ra rằng James đã đưa tùy chọn này vào câu trả lời của mình. Xin lỗi các bạn.
Peter Toth
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.