2010-07-01 38 views
9

Tôi có đối tượng Javascript mà tôi đang cố gắng sử dụng làm "băm". Các phím luôn luôn là dây, vì vậy tôi không nghĩ rằng tôi cần bất cứ điều gì phức tạp như những gì được mô tả trong this SO question. (Tôi cũng không mong đợi số lượng chìa khóa để đi trên khoảng 10 vì vậy tôi không đặc biệt quan tâm đến tra cứu là O (n) so với O (log n) vv)Xác định có bao nhiêu trường đối tượng Javascript có

Chức năng duy nhất tôi muốn các đối tượng Javascript được xây dựng sẵn dường như không có, là một cách nhanh chóng để tìm ra số cặp khóa/giá trị trong đối tượng, giống như những gì trả về của Map.size của Java. Tất nhiên, bạn chỉ có thể làm điều gì đó như:

function getObjectSize(myObject) { 
    var count=0 
    for (var key in myObject) 
    count++ 
    return count 
} 

nhưng điều đó có vẻ như hacky và bùng binh. Có cách nào "đúng" để lấy số trường trong đối tượng không?

+0

Các đề nghị chỉ cho phương pháp của bạn sẽ có thêm một tham số bổ sung để loại trừ/bao gồm tài sản thừa kế, trong trường hợp đó bạn sẽ sử dụng hasOwnProperty thay vì chỉ đơn giản cho vòng lặp –

Trả lời

3

Chỉnh sửa: bạn cần phải kiểm tra myObject.hasOwnProperty(key) trong mỗi lần lặp lại, vì có thể có các thuộc tính được kế thừa. Ví dụ: nếu bạn làm điều này trước vòng lặp Object.prototype.test = 'test', test cũng sẽ được tính.

Và nói về câu hỏi của bạn: bạn chỉ có thể xác định chức năng trợ giúp, nếu tốc độ không quan trọng. Sau khi tất cả, chúng tôi xác định người trợ giúp cho chức năng cắt và những thứ đơn giản khác. Rất nhiều javascript là "loại hacky và roundabout" :)

cập nhật
Ví dụ không thành công, như được yêu cầu.

Object.prototype.test = 'test'; 
var x = {}; 
x['a'] = 1; 
x['b'] = 2; 

Số đếm trở lại sẽ là 3.

+0

Đối tượng được tạo bằng 'myObject = {}' và sau đó các thuộc tính được thêm vào nó với 'myObject [key] = giá trị' trong đó' khóa' luôn là một chuỗi. Vì vậy, tôi nghĩ rằng đó sẽ không phải là một mối quan tâm trong trường hợp này. – MatrixFrog

+0

@MatrixFrog Ồ, thật sao? :) Nó không quan trọng loại là 'chìa khóa'. Tôi đã thêm ví dụ để làm rõ điểm. –

+0

btw, Anurag nhấn cùng một điểm trong câu trả lời của mình (nhận xét trong đó) –

0

bạn cũng có thể chỉ làm myObject.length (trong mảng)

nevermind, thấy điều này: JavaScript object size

+1

Anh ta không hỏi về mảng hoặc cho 'sizeof'. Anh ta muốn số ánh xạ (cặp khóa-giá trị) trong một đối tượng. –

+0

'myObject.length' là suy nghĩ đầu tiên của tôi, nhưng có, nó chỉ hoạt động đối với mảng. – MatrixFrog

+0

BTW, liên kết bạn cung cấp là cho SIZEOF, ví dụ: số byte được sử dụng. OP muốn biết số cặp khóa-giá trị trong một đối tượng. (Tôi gần như đã làm -1 vì đây không phải là câu trả lời cho câu hỏi; tuy nhiên liên kết này rất thú vị, ngay cả khi ở một chủ đề khác.) – ToolmakerSteve

0

Đó là tất cả các bạn có thể làm. Rõ ràng, các đối tượng JavaScript không được thiết kế cho việc này. Và điều này sẽ chỉ cung cấp cho bạn số lượng thuộc tính Enumerable. Hãy thử getObjectSize(Math).

13

Có một cách dễ dàng hơn spec'd trong ECMAScript 5.

Object.keys(..) trả về một mảng của tất cả các phím được xác định trên đối tượng. Chiều dài có thể được gọi trên đó. Hãy thử trong Chrome:

Object.keys({a: 1, b: 2}).length; // 2 

Lưu ý rằng tất cả các đối tượng là cặp khóa/giá trị cơ bản trong JavaScript và chúng cũng rất mở rộng. Bạn có thể mở rộng Object.prototype bằng phương thức size và nhận số đếm ở đó. Tuy nhiên, giải pháp tốt hơn nhiều là tạo giao diện loại HashMap hoặc sử dụng một trong nhiều triển khai hiện có trên mạng và xác định size trên giao diện đó. Đây cũng là loại thực nhỏ:

function HashMap() {} 

HashMap.prototype.put = function(key, value) { 
    this[key] = value; 
}; 

HashMap.prototype.get = function(key) { 
    if(typeof this[key] == 'undefined') { 
     throw new ReferenceError("key is undefined"); 
    } 
    return this[key]; 
}; 

HashMap.prototype.size = function() { 
    var count = 0; 

    for(var prop in this) { 
     // hasOwnProperty check is important because 
     // we don't want to count properties on the prototype chain 
     // such as "get", "put", "size", or others. 
     if(this.hasOwnProperty(prop) { 
      count++; 
     } 
    } 

    return count; 
}; 

Use as (example):

var map = new HashMap(); 
map.put(someKey, someValue); 
map.size(); 
+0

chỉ trả về các phím Enumerable, hasOwnProperty. –

+0

"LoạiError: Object.keys không phải là một chức năng". Tôi đoán tôi nên nói rằng tôi đang làm việc trên một phần mở rộng Firefox, vì vậy nếu nó không hoạt động trong Firefox thì nó khá vô dụng đối với tôi. Tuy nhiên, thông tin tốt cho tương lai. Cảm ơn! – MatrixFrog

+0

@Matthew - vâng, đó là lý do tại sao tôi nói * được định nghĩa trên đối tượng * và có khả năng đếm cũng rất quan trọng, nhưng đó là điều 'for..in' cũng sẽ trở lại, vì vậy tôi đã bỏ nó ra khỏi cuộc thảo luận. @MatrixFrog - Nó sẽ đến trong Firefox 4, và bạn luôn có thể định nghĩa một kiểu đối tượng tùy chỉnh với một phương thức kích thước, như trong ví dụ trên. – Anurag

Các vấn đề liên quan