2008-08-20 33 views
178

Tôi biết trong javascript Objects đôi như băm nhưng tôi đã không thể tìm thấy một xây dựng trong chức năng để có được các phímLàm thế nào để tìm khóa của băm?

var h = {a:'b',c:'d'}; 

Tôi muốn một cái gì đó giống như

var k = h.keys() ; // k = ['a','c']; 

Nó là đơn giản để viết một hàm bản thân mình để lặp qua các mục và thêm các khóa vào một mảng mà tôi quay trở lại, nhưng có cách dọn dẹp chuẩn nào hơn để làm điều đó không?

Tôi tiếp tục cảm thấy nó phải là một chức năng được xây dựng đơn giản mà tôi đã bỏ lỡ nhưng tôi không thể tìm thấy nó!

+0

tôi chỉ cần nhảy vào javascript nhưng bài đăng này có thể giúp bạn. http://dean.edwards.name/weblog/2006/07/enum/ –

+0

Bản sao có thể có của [Lấy mảng khóa của đối tượng] (http://stackoverflow.com/questions/8763125/get-array-of-objects- phím) – blo0p3r

+1

Điều gì về việc nhận được các giá trị từ các phím? Ngoài ra, nhận được số lượng các khóa trong một băm. –

Trả lời

249

Có chức năng trong javascript hiện đại (ECMAScript 5) gọi là Object.keys thực hiện hoạt động này:

var obj = { "a" : 1, "b" : 2, "c" : 3}; 
alert(Object.keys(obj)); // will output ["a", "b", "c"] 

chi tiết Khả năng tương thích có thể được tìm thấy here.

On Mozilla site đó cũng là một Snipped cho tương thích ngược:

if(!Object.keys) Object.keys = function(o){ 
    if (o !== Object(o)) 
     throw new TypeError('Object.keys called on non-object'); 
    var ret=[],p; 
    for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p); 
    return ret; 
} 
+0

điều này sẽ không tự nhiên hơn? 'if (! Object.prototype.keys) Object.prototype.keys = function() { nếu (this! == Object (this)) ném TypeError mới ('Object.keys gọi là non-object'); var ret = [], p; cho (p trong này) nếu (Object.prototype.hasOwnProperty.call (this, p)) ret.push (p); trả lại; } var x = {a: {A: 1, B: 2, C: 3}, b: {A: 10, B: 20}}; alert (x.a.keys()); ' – ekkis

+2

Khi tôi hiểu được' Object.prototype.keys' này sẽ làm cho 'keys' có sẵn cho tất cả các lớp con của Object, do đó cho tất cả các đối tượng. Mà có lẽ bạn muốn nếu bạn đang cố gắng sử dụng OOP. Dù sao điều này thực sự phụ thuộc vào yêu cầu của bạn. –

+1

Nếu bạn sử dụng mootools, Object.keys() sẽ có sẵn trong tất cả các trình duyệt. – thepeer

13

này là tốt nhất bạn có thể làm, như xa như tôi biết ...

var keys = []; 
for (var k in h)keys.push(k); 
+2

Điều này cũng không hoạt động khi Object.prototype bị rối tung. – Phil

+4

Nó sẽ là tốt hơn để sử dụng này, và không phải để "mess với" Object.prototype. Dường như mọi thứ đều hỏng nếu chúng ta thêm đồ vật vào Object.prototype: nó là một thành ngữ cực kỳ phổ biến để lặp qua các khóa của một mảng/đối tượng. –

6

Tôi tin rằng bạn lặp qua các thuộc tính của đối tượng có thể sử dụng cho/trong, vì vậy bạn có thể làm một cái gì đó như thế này :

function getKeys(h) { 
    Array keys = new Array(); 
    for (var key in h) 
    keys.push(key); 
    return keys; 
} 
+0

Điều này không hiệu quả, hãy xem câu trả lời của Annan – Phil

79

Đối với mã sản xuất đòi hỏi một khả năng tương thích với các trình duyệt lớn khách hàng tôi vẫn đề nghị trả lời Ivan Nevostruev của trên với shim để đảm bảo Object.keys trong trình duyệt cũ. Tuy nhiên, có thể nhận được chức năng chính xác được yêu cầu bằng tính năng defineProperty mới của ECMA.

Tính đến ECMAScript 5 - Object.defineProperty

Tính đến ECMA5 bạn có thể sử dụng Object.defineProperty() để xác định tính chất phi đếm được. Các current compatibility vẫn có nhiều để được mong muốn, nhưng điều này cuối cùng sẽ trở thành có thể sử dụng trong tất cả các trình duyệt. (Cụ thể lưu ý không tương thích hiện tại với IE8!)

Object.defineProperty(Object.prototype, 'keys', { 
    value: function keys() { 
    var keys = []; 
    for(var i in this) if (this.hasOwnProperty(i)) { 
     keys.push(i); 
    } 
    return keys; 
    }, 
    enumerable: false 
}); 

var o = { 
    'a': 1, 
    'b': 2 
} 

for (var k in o) { 
    console.log(k, o[k]) 
} 

console.log(o.keys()) 

# OUTPUT 
# > a 1 
# > b 2 
# > ["a", "b"] 

Tuy nhiên, vì ECMA5 đã thêm Object.keys bạn cũng có thể sử dụng:

Object.defineProperty(Object.prototype, 'keys', { 
    value: function keys() { 
    return Object.keys(this); 
    }, 
    enumerable: false 
}); 

câu trả lời gốc

Object.prototype.keys = function() 
{ 
    var keys = []; 
    for(var i in this) if (this.hasOwnProperty(i)) 
    { 
    keys.push(i); 
    } 
    return keys; 
} 

Chỉnh sửa: Kể từ khi câu trả lời này đã được khoảng một thời gian tôi sẽ để lại ở trên bị ảnh hưởng. Bất cứ ai đọc điều này cũng nên đọc câu trả lời của Ivan Nevostruev dưới đây.

Không có cách nào để tạo các hàm nguyên mẫu không thể đếm được dẫn đến chúng luôn bật lên trong các vòng lặp for-in không sử dụng hasOwnProperty. Tôi vẫn nghĩ câu trả lời này sẽ là lý tưởng nếu mở rộng nguyên mẫu của Object không quá lộn xộn.

+9

'hasOwnProperty' loại trừ các thuộc tính trên nguyên mẫu của đối tượng này, điều này rất hữu ích để biết. – ijw

+2

Câu trả lời được chấp nhận bởi vì đó là cách tôi đã kết thúc việc triển khai nó nhưng tôi cảm thấy điều này phải là một chức năng tích hợp của ngôn ngữ. – Pat

+5

Lưu ý rằng bạn nên sử dụng "for (var i in this) ..." để tránh tạo biến toàn cục. –

4

Tôi muốn sử dụng đánh giá câu trả lời hàng đầu phía trên

Object.prototype.keys = function() ... 

Tuy nhiên khi sử dụng kết hợp với bản đồ google API v3, google bản đồ là không có chức năng.

for (var key in h) ... 

hoạt động tốt.

34

Bạn có thể sử dụng Underscore.js, mà là một thư viện tiện ích Javascript.

_.keys({one : 1, two : 2, three : 3}); 
// => ["one", "two", "three"] 
+0

Vâng, nó không thực sự là những gì được hỏi, bởi vì @Pat đang tìm kiếm một hàm dựng sẵn, nhưng nó là một thư viện thú vị, và nó không sửa đổi 'Object.prototype' – fresskoma

+2

Những ngày này, tôi nghĩ nó hữu ích hơn nhiều để sử dụng những thư viện nhỏ tiện lợi này hơn là viết các triển khai của riêng bạn ... Dù sao, trong hầu hết các dự án trong thế giới thực, chúng tôi đang sử dụng các thư viện dưới dạng tương đương hoặc dưới dạng tương đương. Cá nhân, tôi muốn đi với Underscore. –

+0

'_.keys (obj) .length' để xem có phím nào không. – chovy

9

sử dụng jquery bạn có thể nhận được các phím như thế này ...

var bobject = {primary:"red",bg:"maroon",hilite:"green"}; 
var keys = []; 
$.each(bobject, function(key,val){ keys.push(key); }); 
console.log(keys); // ["primary", "bg", "hilite"] 

Hoặc -

var bobject = {primary:"red",bg:"maroon",hilite:"green"}; 
$.map(bobject, function(v,k){return k;}); 

nhờ @pimlottc

+3

Nếu bạn muốn đi tuyến đường này, bạn cũng có thể sử dụng 'JQuery.map': ' $ .map (h, hàm (v, k) {return k;}); ' – pimlottc

1

nếu bạn đang cố gắng để có được chỉ các phần tử chứ không phải chức năng thì mã này có thể giúp bạn

this.getKeys = function() { 

var keys = new Array(); 
for(var key in this) { 

    if(typeof this[key] !== 'function') { 

     keys.push(key); 
    } 
} 
return keys; 

}

này là một phần của việc thực hiện của tôi về HashMap và tôi chỉ muốn các phím, this là đối tượng hashmap có chứa các phím

38

bạn có thể sử dụng Object.keys

Object.keys(h) 
+3

Được thêm vào ECMAScript 5 nhưng nên hoạt động trong hầu hết các trình duyệt chính hiện nay – Pat

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