Câu trả lời:
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 keys = Object.keys(myObject);
Trên đây có một polyfill đầy đủ nhưng một phiên bản đơn giản là:
var getKeys = function(obj){
var keys = [];
for(var key in obj){
keys.push(key);
}
return keys;
}
Thay thế var getKeys
bằng Object.prototype.keys
để cho phép bạn gọi .keys()
trên bất kỳ đối tượng. Mở rộng nguyên mẫu có một số tác dụng phụ và tôi không khuyên bạn nên làm điều đó.
for (var key in myObject) {...}
kỹ thuật rất hữu ích cho runtimes javascript bên ngoài các trình duyệt và V8. Ví dụ: khi chuyển các truy vấn giảm bản đồ javascript vào Rịa, Object
đối tượng không tồn tại, vì vậy Object.keys
phương thức này không khả dụng.
Object.keys
chỉ trả về các thuộc tính của đối tượng. Tôi thấy đó là một sự khác biệt quan trọng.
Như slashnick đã chỉ ra, bạn có thể sử dụng cấu trúc "for in" để lặp lại một đối tượng cho tên thuộc tính của nó. Tuy nhiên, bạn sẽ lặp lại tất cả các tên thuộc tính trong chuỗi nguyên mẫu của đối tượng. Nếu bạn muốn lặp chỉ trên thuộc tính riêng của đối tượng, bạn có thể tận dụng các Object # hasOwnProperty () phương pháp. Do đó có những điều sau đây.
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
/* useful code here */
}
}
esc
phím vì đối tượng có khoảng một triệu tài sản, hầu hết chúng không được sử dụng và tôi đã có một cảnh báo về nó.
Như Sam Dutton đã trả lời, một phương pháp mới cho chính mục đích này đã được giới thiệu trong ECMAScript Edition Edition. Object.keys()
sẽ làm những gì bạn muốn và được hỗ trợ trong Firefox 4 , Chrome 6, Safari 5 và IE 9 .
Bạn cũng có thể dễ dàng thực hiện phương thức trong các trình duyệt không hỗ trợ. Tuy nhiên, một số triển khai ngoài đó không tương thích hoàn toàn với Internet Explorer. Đây là một giải pháp tương thích hơn:
Object.keys = Object.keys || (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
DontEnums = [
'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
],
DontEnumsLength = DontEnums.length;
return function (o) {
if (typeof o != "object" && typeof o != "function" || o === null)
throw new TypeError("Object.keys called on a non-object");
var result = [];
for (var name in o) {
if (hasOwnProperty.call(o, name))
result.push(name);
}
if (hasDontEnumBug) {
for (var i = 0; i < DontEnumsLength; i++) {
if (hasOwnProperty.call(o, DontEnums[i]))
result.push(DontEnums[i]);
}
}
return result;
};
})();
Lưu ý rằng câu trả lời hiện được chấp nhận không bao gồm kiểm tra hasOwnProperty () và sẽ trả về các thuộc tính được kế thừa thông qua chuỗi nguyên mẫu. Nó cũng không giải thích cho lỗi DontEnum nổi tiếng trong Internet Explorer nơi các thuộc tính không thể đếm được trên chuỗi nguyên mẫu khiến các thuộc tính được khai báo cục bộ có cùng tên để thừa hưởng thuộc tính DontEnum của chúng.
Việc triển khai Object.keys () sẽ cung cấp cho bạn một giải pháp mạnh mẽ hơn.
EDIT: sau một cuộc thảo luận gần đây với kangax , một người đóng góp nổi tiếng cho Prototype, tôi đã triển khai cách khắc phục lỗi DontEnum dựa trên mã cho Object.forIn()
chức năng của anh ta được tìm thấy ở đây .
Object.prototype
. Mặc dù vậy, thông thường, mã ngắn hơn trông hấp dẫn hơn đáng kể so với mã lớn hơn, mạnh hơn, nhưng điểm của câu trả lời này là sử dụng ECMAScript 5 Object.keys()
, có thể được triển khai trong các trình duyệt không hỗ trợ sử dụng mã này. Phiên bản gốc sẽ còn hiệu quả hơn thế này.
Object.keys
chỉ trả về một mảng các chuỗi tương ứng với đếm được thuộc tính của một đối tượng. Điều này có thể không quan trọng khi làm việc với các đối tượng gốc (do người dùng xác định), nhưng sẽ hiển thị rất nhiều với các đối tượng máy chủ (mặc dù hành vi của đối tượng máy chủ không xác định là một câu chuyện riêng - đau đớn). Để liệt kê TẤT CẢ các thuộc tính (bao gồm cả không thể đếm được), ES5 cung cấp Object.getOwnPropertyNames
(xem hỗ trợ của nó trong bảng tổng hợp của tôi - kangax.github.com/es5-compat-table )
Object.keys(stuff)
và không stuff.keys()
?
Lưu ý rằng Object.keys và các phương thức ECMAScript 5 khác được Firefox 4, Chrome 6, Safari 5, IE 9 trở lên hỗ trợ.
Ví dụ:
var o = {"foo": 1, "bar": 2};
alert(Object.keys(o));
Bảng tương thích ECMAScript 5: http : // Khangax.github.com/es5-compat-table/
Mô tả các phương thức mới: http://markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/
Object.getOwnPropertyNames(obj)
Hàm này cũng hiển thị các thuộc tính không thể đếm được ngoài các thuộc tính được hiển thị bởi Object.keys(obj)
.
Trong JS, mọi thuộc tính đều có một vài thuộc tính, bao gồm cả boolean enumerable
.
Nói chung, các thuộc tính không thể đếm được là "nội tâm" hơn và ít được sử dụng hơn, nhưng đôi khi thật sâu sắc khi nhìn vào chúng để xem điều gì đang thực sự xảy ra.
Thí dụ:
var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})
console.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]
console.log(Object.keys(o))
// [ 'yes' ]
for (var x in o)
console.log(x)
// yes, base
Cũng lưu ý cách làm:
Object.getOwnPropertyNames
và Object.keys
không đi lên chuỗi nguyên mẫu để tìmbase
for in
làmTìm hiểu thêm về chuỗi nguyên mẫu tại đây: https://stackoverflow.com/a/23877420/895245
Tôi là một fan hâm mộ lớn của chức năng kết xuất.
http://ajaxian.com/archives/javascript-variable-dump-in-coldfusion
https://j11y.io/demos/prettyprint/
?
nếu bạn đang cố gắng chỉ lấy các phần tử nhưng không phải các hàm 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;
}
đây là một phần trong quá trình triển khai HashMap của tôi và tôi chỉ muốn các khóa, "đây" là đối tượng hashmap chứa các khóa
Điều này sẽ hoạt động trong hầu hết các trình duyệt, ngay cả trong IE8 và không có thư viện thuộc bất kỳ loại nào được yêu cầu. var i là chìa khóa của bạn.
var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);
Mozilla có đầy đủ chi tiết triển khai về cách thực hiện trong trình duyệt không được hỗ trợ, nếu điều đó giúp:
if (!Object.keys) {
Object.keys = (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function (obj) {
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
var result = [];
for (var prop in obj) {
if (hasOwnProperty.call(obj, prop)) result.push(prop);
}
if (hasDontEnumBug) {
for (var i=0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
}
}
return result;
};
})();
}
Bạn có thể bao gồm nó theo cách bạn muốn, nhưng có thể trong một số loại extensions.js
tệp ở đầu ngăn xếp tập lệnh của bạn.
Sử dụng Reflect.ownKeys()
var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]
Object.keys và Object.getOwnPropertyNames không thể có được các thuộc tính không thể đếm được . Nó hoạt động ngay cả đối với các thuộc tính không thể đếm được .
var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]
IE không hỗ trợ (i in obj) cho các thuộc tính gốc. Dưới đây là danh sách tất cả các đạo cụ tôi có thể tìm thấy.
Có vẻ như stackoverflow thực hiện một số bộ lọc ngu ngốc.
Danh sách có sẵn ở cuối bài đăng trên nhóm google này: - https://groups.google.com/group/hackvertor/browse_thread/thread/a9ba81ca642a63e0
Vì tôi sử dụng underscore.js trong hầu hết mọi dự án, tôi sẽ sử dụng keys
hàm:
var obj = {name: 'gach', hello: 'world'};
console.log(_.keys(obj));
Đầu ra của nó sẽ là:
['name', 'hello']
Giải pháp hoạt động trên các trường hợp của tôi và trình duyệt chéo:
var getKeys = function(obj) {
var type = typeof obj;
var isObjectType = type === 'function' || type === 'object' || !!obj;
// 1
if(isObjectType) {
return Object.keys(obj);
}
// 2
var keys = [];
for(var i in obj) {
if(obj.hasOwnProperty(i)) {
keys.push(i)
}
}
if(keys.length) {
return keys;
}
// 3 - bug for ie9 <
var hasEnumbug = !{toString: null}.propertyIsEnumerable('toString');
if(hasEnumbug) {
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
var nonEnumIdx = nonEnumerableProps.length;
while (nonEnumIdx--) {
var prop = nonEnumerableProps[nonEnumIdx];
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
keys.push(prop);
}
}
}
return keys;
};
_.keys(myJSONObject)