Câu hỏi Độ dài của đối tượng JavaScript


Nếu tôi có một đối tượng JavaScript, hãy nói

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

có cách thức thực hành tốt nhất được chấp nhận hay được chấp nhận để có được độ dài của đối tượng này không?


1827
2017-08-07 19:42


gốc


Đối tượng literals trong javascript là mặc định mảng kết hợp ví dụ object.propertyName.propertyValue là giống như đối tượng [propertyName] [propertyValue] - neitony
Đã thêm một lớp lót trong Underscore.js thực hiện điều này: stackoverflow.com/a/11346637/11236 - ripper234
Một khi câu trả lời dòng là sử dụng Object.keys (myArray) .length như @aeosynth nói. - Ranadheer Reddy
ok, thế còn Object.keys(obj).length - Muhammad Umer
Tại sao object.length không hợp lệ? Nó trả về kết quả chính xác cho tôi. - Adrian M


Các câu trả lời:


Câu trả lời mạnh mẽ nhất (tức là nắm bắt được ý định của những gì bạn đang cố gắng làm trong khi gây ra các lỗi nhỏ nhất) sẽ là:

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

// Get the size of an object
var size = Object.size(myArray);

Có một loại quy ước trong JavaScript mà bạn đừng thêm đồ vật vào Object.prototype, bởi vì nó có thể phá vỡ liệt kê trong các thư viện khác nhau. Tuy nhiên, việc thêm các phương thức vào Object thường là an toàn.


Đây là bản cập nhật kể từ năm 2016 và triển khai rộng rãi ES5 và hơn thế nữa.  Đối với IE9 + và tất cả các trình duyệt có khả năng hiện đại khác của ES5 +, bạn có thể sử dụng Object.keys() vì vậy mã trên chỉ trở thành:

var size = Object.keys(myObj).length;

Điều này không phải sửa đổi bất kỳ mẫu thử nghiệm hiện có kể từ Object.keys() hiện được tích hợp sẵn.

Chỉnh sửa: Các đối tượng có thể có các thuộc tính biểu tượng không thể được trả về thông qua phương thức Object.key. Vì vậy, câu trả lời sẽ không đầy đủ mà không nhắc đến chúng.

Loại ký hiệu đã được thêm vào ngôn ngữ để tạo số nhận dạng duy nhất cho thuộc tính đối tượng. Lợi ích chính của loại Biểu tượng là ngăn ngừa ghi đè.

Object.keys hoặc là Object.getOwnPropertyNames không hoạt động cho các thuộc tính tượng trưng. Để trả lại, bạn cần sử dụng Object.getOwnPropertySymbols.

var person = {
  [Symbol('name')]: 'John Doe',
  [Symbol('age')]: 33,
  "occupation": "Programmer"
};

const propOwn = Object.getOwnPropertyNames(person);
console.log(propOwn.length); // 1

let propSymb = Object.getOwnPropertySymbols(person);
console.log(propSymb.length); // 2

2022
2017-08-09 08:31



@Tres - mã của bạn có thể bị hỏng nếu ai đó đến và vượt qua thuộc tính 'kích thước' mà không biết bạn đã tuyên bố nó đã ở đâu đó trong mã, do đó, nó luôn kiểm tra nếu nó đã được xác định - vsync
@ vsync Bạn rất chính xác. Người ta phải luôn luôn thực hiện kiểm tra sanity cần thiết :) - Tres
Tại sao mọi người bỏ qua điều này: Object.keys(obj).length - Muhammad Umer
@MuhammadUmer Có lẽ vì phương pháp đó thậm chí không tồn tại khi câu trả lời này được viết. Thậm chí ngày nay, việc sử dụng nó có lẽ sẽ yêu cầu một polyfill cho các trình duyệt cũ. - Chris Hayes
@stonyau IE8, IE9, IE10 là các trình duyệt đã chết mà không nhận được sự hỗ trợ từ Microsoft. Người dùng IE8, IE9, IE10 nhận được thông báo từ Microsoft, rằng họ sử dụng trình duyệt cũ, không được hỗ trợ và sẽ mong đợi rằng nội dung đó sẽ không hoạt động đối với họ. support.microsoft.com/en-us/kb/3123303 - Lukas


Nếu bạn biết bạn không phải lo lắng về hasOwnProperty kiểm tra, bạn có thể làm điều này rất đơn giản:

Object.keys(myArray).length

1413
2018-04-03 01:44



tại sao không? từ những gì tôi biết, nó là một tiêu chuẩn: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/… - vsync
Nó không phải là một phổ đã thực hiện nhưng bạn có thể kiểm tra xem trình duyệt nào hỗ trợ nó cái bàn này. - aeosynth
Không hỗ trợ IE8 = không đi. - ripper234
thời gian để chuyển sang firefox = không may, bạn chuyển đổi không có nghĩa là người dùng trang web của bạn sẽ ... - mdup
@ ripper234 không hỗ trợ IE = thời gian để chèn lấp - John Dvorak


Đã cập nhật: Nếu bạn đang sử dụng Underscore.js (đề nghị, nó nhẹ!), sau đó bạn chỉ có thể làm

_.size({one : 1, two : 2, three : 3});
=> 3

Nếu khôngvà bạn không muốn lộn xộn xung quanh với các thuộc tính của Object vì bất kỳ lý do gì và đã sử dụng jQuery, một plugin có thể truy cập như nhau:

$.assocArraySize = function(obj) {
    // http://stackoverflow.com/a/6700/11236
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

252
2017-07-05 14:39



_.size() là giải pháp hoàn hảo cho tôi Sao băng dự án có hỗ trợ underscore.js. - tokyovariable
Tôi sử dụng gạch dưới và bài đăng này chỉ nhắc tôi rằng tôi không sử dụng nó đủ trong dự án này. Nếu bạn xử lý các đối tượng, bạn nên có sẵn underscore.js. - jbolanos
Dấu gạch dưới> (tất cả - ['lo-dấu gạch ngang']) - Rayjax
Cũng có lodash.js  lodash - hipkiss
@Babydead để phân biệt các thuộc tính thực sự của đối tượng so với các đối tượng thừa kế. developer.mozilla.org/en/docs/Web/JavaScript/Reference/… - ripper234


Sử dụng một cái gì đó đơn giản như:

Object.keys(obj).length

Nó không phải là khó khăn và chắc chắn không yêu cầu một chức năng khác để thực hiện.


153
2017-10-27 03:46



Điều này khác với câu trả lời của aeosynth như thế nào? - DanMan
Bạn đã thấy số câu trả lời cho câu hỏi này chưa? Khi tôi viết nó, tôi không thấy (một vài) bản sao. James Coglan đã trả lời bằng cách này 3 năm trước khi aeosynth, vì vậy bạn đã không đọc tất cả các câu trả lời hoặc .... hoặc bạn đã thấy điều đó. - Michael
@ Michael không, anh ấy không làm thế. Đó là bản chỉnh sửa của một người dùng khác vào ngày 02-28-2016. ôn tập - old_mountain


Đây là giải pháp đa trình duyệt nhất.

Điều này là tốt hơn so với câu trả lời được chấp nhận bởi vì nó sử dụng Object.keys gốc nếu tồn tại. Vì vậy, nó là nhanh nhất cho tất cả các trình duyệt hiện đại.

if (!Object.keys) {
    Object.keys = function (obj) {
        var arr = [],
            key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                arr.push(key);
            }
        }
        return arr;
    };
}

Object.keys(obj).length;

43
2017-09-01 16:12



Object.keys() trả về một mảng chứa tên của chỉ những thuộc tính được liệt kê. Nếu bạn muốn một mảng với TẤT CẢ các thuộc tính, bạn nên sử dụng Object.getOwnPropertyNames() thay thế. Xem developer.mozilla.org/en/docs/Web/JavaScript/Reference/… - John Slegers


Tôi không phải là chuyên gia JavaScript, nhưng có vẻ như bạn sẽ phải lặp qua các phần tử và đếm chúng vì Object không có một phương thức chiều dài:

var element_count = 0;
for (e in myArray) {  if (myArray.hasOwnProperty(e)) element_count++; }

@palmsey: Trong sự công bằng cho OP, tài liệu JavaScript thực sự chỉ rõ ràng sử dụng các biến kiểu Object theo cách này là "mảng kết hợp".


27
2017-08-07 19:52



Sẽ không hoạt động, bởi vì nó sẽ đếm phương pháp quá, được thêm vào thông qua nguyên mẫu. - Lajos Meszaros


Phương thức này nhận tất cả các tên thuộc tính của đối tượng của bạn trong một mảng, do đó bạn có thể nhận được độ dài của mảng đó bằng với chiều dài khóa của đối tượng của bạn.

Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2

25
2017-07-01 12:40



Tôi thích phương pháp này vì nó gọi nội bộ là "hasOwnProperty" nên nó không đẩy các tên thuộc tính được thừa hưởng từ chuỗi nguyên mẫu, và nó là một lớp lót giống như Object.keys(...).lengthnhưng an toàn hơn nhiều vì lý do tôi vừa nói. - Patrick Roberts
Phương pháp khóa @PatrickRoberts không trả về các thuộc tính từ chuỗi nguyên mẫu. Vậy tại sao cần có hasOwnProperty ở đây. Ngoài ra getOwnProperty sẽ trả về các thuộc tính ẩn, vì độ dài nằm trong mảng vv - Muhammad Umer
@MuhammadUmer "Nếu tôi có một mảng kết hợp JavaScript ..." đây là một đối tượng, không phải là một mảng. length là một thuộc tính của cá thể Array, do đó nó phải được tính trong chiều dài của các khóa. Và có bạn là chính xác về chuỗi nguyên mẫu, tôi thu hồi tuyên bố đó. Những gì tôi muốn nói là nói chung bạn sẽ muốn ngay cả những thuộc tính không thể đếm được nếu bạn có một đối tượng không giống như Array, bởi vì một Array đã có một length để bắt đầu. - Patrick Roberts
hiện công việc này trong IE-8 - marcusshep


Để không gây rối với mẫu thử nghiệm hoặc mã khác, bạn có thể xây dựng và mở rộng đối tượng của riêng mình:

function Hash(){
    var length=0;
    this.add = function(key, val){
         if(this[key] == undefined)
         {
           length++;
         }
         this[key]=val;
    }; 
    this.length = function(){
        return length;
    };
}

myArray = new Hash();
myArray.add("lastname", "Simpson");
myArray.add("age", 21);
alert(myArray.length()); // will alert 2

Nếu bạn luôn sử dụng phương thức thêm, thuộc tính độ dài sẽ chính xác. Nếu bạn lo lắng rằng bạn hoặc người khác quên sử dụng nó, bạn có thể thêm bộ đếm thuộc tính mà những người khác đã đăng lên phương thức chiều dài.

Tất nhiên, bạn luôn có thể ghi đè lên các phương pháp. Nhưng ngay cả khi bạn làm như vậy, mã của bạn có thể sẽ thất bại đáng kể, khiến cho việc gỡ lỗi trở nên dễ dàng. ;)


19
2018-06-11 15:44



Tôi nghĩ rằng đây là giải pháp tốt nhất vì nó không yêu cầu lặp với 'for' có thể tốn kém nếu mảng lớn - Digitlimit


Đây là cách làm và đừng quên kiểm tra xem thuộc tính có nằm trong chuỗi nguyên mẫu không:

var element_count = 0;
for(var e in myArray)
    if(myArray.hasOwnProperty(e))
        element_count++;

14
2017-08-08 19:18