Làm thế nào để truy cập thuộc tính đầu tiên của một đối tượng Javascript?


611

Có cách nào thanh lịch để truy cập vào tài sản đầu tiên của một đối tượng ...

  1. nơi bạn không biết tên tài sản của bạn
  2. không sử dụng vòng lặp như for .. inhoặc jQuery$.each

Ví dụ, tôi cần truy cập vào foo1đối tượng mà không biết tên của foo1:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

1
Có lẽ tốt hơn là chuyển đổi nó thành Mảng trước
cregox

Câu trả lời:


1393
var obj = { first: 'someVal' };
obj[Object.keys(obj)[0]]; //returns 'someVal'

Sử dụng điều này bạn có thể truy cập các thuộc tính khác bằng chỉ mục. Hãy nhận biết tho! Object.keysthứ tự trả lại không được đảm bảo theo ECMAScript tuy nhiên không chính thức bởi tất cả các cài đặt trình duyệt chính, vui lòng đọc https://stackoverflow.com/a/23202095 để biết chi tiết về điều này.


25
Bạn nói rằng đó không phải là cách nhanh nhất. Cách nào sẽ nhanh hơn?
T Nguyễn

3
Điều này không hiệu quả lắm vì nó tạo ra một mảng toàn bộ các khóa của đối tượng.
Andrew Mao

9
@T Nguyễn Tôi sẽ đăng nó nếu tôi biết điều đó :)
Grzegorz Kaczan

5
@DavChana - Bạn đã thiết lập điểm chuẩn sai. Khối soạn sẵn sẽ luôn luôn được thực thi và khối 2 của bạn trống, có nghĩa là kết quả đầu tiên đại diện cho bản ghi thực thi + khối1 và kết quả thứ hai chỉ đại diện cho bản tóm tắt . Đây là điểm chuẩn chính xác: http://jsben.ch/#/R9aLQ , cho thấy chúng khá giống nhau (chạy thử nghiệm nhiều lần).
myfunkyside

9
Tôi muốn first()hoặc một cái gì đó tương tự có thể xử lý này.
Fr0zenFyr

113

Hãy thử for … invòng lặp và ngắt sau lần lặp đầu tiên:

for (var prop in object) {
    // object[prop]
    break;
}

1
Tôi nghĩ rằng đây là về lựa chọn duy nhất. Tôi không chắc chắn rằng bạn đảm bảo rằng các thuộc tính sẽ được lặp đi lặp lại theo thứ tự có thể dự đoán / hữu ích. Tức là bạn có thể có ý định foo1 nhưng nhận foo3. Nếu các thuộc tính được đánh số như trong ví dụ, bạn có thể thực hiện một chuỗi so sánh để xác định định danh kết thúc bằng '1'. Sau đó, một lần nữa, nếu thông thường là mối quan tâm chính của bộ sưu tập, có lẽ bạn nên sử dụng một mảng thay vì một đối tượng.
hấp25

2
Nếu bất cứ ai khác quan tâm đến thứ tự, hầu hết các trình duyệt đều có thể dự đoán được: stackoverflow.com/questions/280713/ mẹo
Flash

6
var prop; cho (prop trong đối tượng) phá vỡ; // đối tượng [prop]
netiul

12
Câu trả lời cũ nhưng. Bạn có thể muốn kiểm tra nếu tài sản thuộc về đối tượng. như: for (..) {if (! obj.hasOwnProperty (prop)) tiếp tục; .... phá vỡ; } chỉ trong trường hợp đối tượng thực sự trống rỗng, nó không đi ngang qua nguyên mẫu hoặc thứ gì đó.
pgarciacamou

65

Bạn cũng có thể làm Object.values(example)[0].


Điều này không có sẵn trong tất cả các trình duyệt, tham khảo stackoverflow.com/a/38748490/719689
AlxVallejo

1
Tôi thích điều này hơn Object.keys, bởi vì bạn được đảm bảo để có được mục đầu tiên.
theStherSide

Cập nhật từ năm 2019, tôi nghĩ rằng điều này hoạt động trên hầu hết các trình duyệt ngoại trừ nhà phát triển
IE.mozilla.org/en-US/docs/Web/JavaScript/Reference/ trộm

46

Sử dụng Object.keysđể có được một mảng các thuộc tính trên một đối tượng. Thí dụ:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

var keys = Object.keys(example); // => ["foo1", "foo2", "foo3"] (Note: the order here is not reliable)

Tài liệu và shim trình duyệt chéo được cung cấp ở đây . Một ví dụ về việc sử dụng nó có thể được tìm thấy trong một câu trả lời khác của tôi ở đây .

Chỉnh sửa : để rõ ràng, tôi chỉ muốn lặp lại những gì đã được nêu chính xác trong các câu trả lời khác: thứ tự chính trong các đối tượng javascript không được xác định.


25

Phiên bản một quy tắc:

var val = example[function() { for (var k in example) return k }()];

2
Đôi khi có thể gặp rủi ro khi sử dụng for inmà không kiểm tra hasOwnPropertyvì đối tượng chứa các giá trị không mong muốn khác được thêm vào theo chương trình để cuối cùng bạn có thể nhận được kết quả không mong muốn từ đoạn trích này. Chỉ vì nó ngắn và gọn gàng không có nghĩa là tối ưu an toàn.
Javier Cobos

24

Không có tài sản "đầu tiên". Các phím đối tượng không có thứ tự.

Nếu bạn lặp lại chúng với (var foo in bar)bạn, bạn sẽ nhận được chúng theo một số thứ tự, nhưng nó có thể thay đổi trong tương lai (đặc biệt là nếu bạn thêm hoặc xóa các khóa khác).


Tuyệt vời. Tôi đã sử dụng một đối tượng để thực hiện bản đồ duy trì thứ tự chèn. Điều đó sẽ phá vỡ khi tôi xóa một giá trị vì lần chèn tiếp theo sẽ lấp đầy khoảng trống. :(
David Harkness

2
thứ tự khóa / giá trị nên được giữ nguyên trong các phiên bản mới hơn của JS
Alexander Mills

11

Giải pháp với thư viện lodash :

_.find(example) // => {name: "foo1"}

nhưng không có gì đảm bảo về thứ tự lưu trữ nội bộ thuộc tính đối tượng vì nó phụ thuộc vào việc triển khai VM javascript.


2
Chỉ cần thử nghiệm này, và nó không hoạt động. Nó chỉ trả về giá trị, không phải cặp khóa / giá trị.
Chris Haines

2
Không có đề cập nào trong câu hỏi rằng nó sẽ trả về cặp khóa / giá trị, anh ta chỉ yêu cầu đối tượng và câu trả lời được chấp nhận thực hiện nhiều như hàm lodash này: nó trả về nội dung của thuộc tính đầu tiên. Nó có thể không phù hợp với nhu cầu cụ thể của bạn, nhưng câu trả lời này là chính xác dựa trên câu hỏi ban đầu.
Carrm

Có, công việc rất hữu ích khi bạn biết đối tượng của mình sẽ chỉ có một đối tượng convar object = { childIndex: { .. } }; var childObject = _.find(Object);
Raja Khoury

9

Không. Một đối tượng theo nghĩa đen, như được định nghĩa bởi MDC là:

một danh sách gồm 0 hoặc nhiều cặp tên thuộc tính và các giá trị liên quan của một đối tượng, được đặt trong dấu ngoặc nhọn ({}).

Do đó, một đối tượng bằng chữ không phải là một mảng và bạn chỉ có thể truy cập các thuộc tính bằng tên rõ ràng của chúng hoặc một forvòng lặp sử dụng intừ khóa.


25
Đối với những người khác chỉ nhìn thấy dấu tick màu xanh lá cây trong câu trả lời này, có một giải pháp khác tiếp tục xuống trang với 350 lượt upvote.
redfox05

7

Câu trả lời hàng đầu có thể tạo ra toàn bộ mảng và sau đó chụp từ danh sách. Đây là một phím tắt hiệu quả khác

var obj = { first: 'someVal' };
Object.entries(obj)[0][1] // someVal

3

Điều này đã được đề cập ở đây trước đây.

Khái niệm đầu tiên không áp dụng cho các thuộc tính đối tượng và thứ tự của một vòng lặp for ... không được đảm bảo bởi các thông số kỹ thuật, tuy nhiên trong thực tế, nó đáng tin cậy là FIFO ngoại trừ phê bình cho chrome ( báo cáo lỗi ). Đưa ra quyết định của bạn cho phù hợp.


3

Tôi không khuyên bạn nên sử dụng Object.keys vì nó không được hỗ trợ trong các phiên bản IE cũ. Nhưng nếu bạn thực sự cần điều đó, bạn có thể sử dụng mã ở trên để đảm bảo khả năng tương thích trở lại:

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;
}})()};

Tính năng Firefox (Tắc kè) 4 (2.0) Chrome 5 Internet Explorer 9 Opera 12 Safari 5

Thông tin thêm: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys

Nhưng nếu bạn chỉ cần cái đầu tiên, chúng tôi có thể sắp xếp một giải pháp ngắn hơn như:

var data = {"key1":"123","key2":"456"};
var first = {};
for(key in data){
    if(data.hasOwnProperty(key)){
        first.key = key;
        first.content =  data[key];
        break;
    }
}
console.log(first); // {key:"key",content:"123"}

2

Để có được tên khóa đầu tiên trong đối tượng bạn có thể sử dụng:

var obj = { first: 'someVal' };
Object.keys(obj)[0]; //returns 'first'

Trả về một chuỗi, vì vậy bạn không thể truy cập các đối tượng lồng nhau nếu có, như:

var obj = { first: { someVal : { id : 1} }; Ở đây với giải pháp đó bạn không thể truy cập id.

Giải pháp tốt nhất nếu bạn muốn có được đối tượng thực tế là sử dụng lodash như:

obj[_.first(_.keys(obj))].id

Để trả về giá trị của khóa đầu tiên, (nếu bạn không biết chính xác tên khóa đầu tiên):

var obj = { first: 'someVal' };
obj[Object.keys(obj)[0]]; //returns 'someVal'

nếu bạn biết tên khóa chỉ cần sử dụng:

obj.first

hoặc là

obj['first']

0

Nếu bạn cần truy cập vào "thuộc tính đầu tiên của một đối tượng", điều đó có thể có nghĩa là có gì đó không đúng với logic của bạn. Thứ tự của các thuộc tính không phải là vấn đề.


Bạn đúng. Tôi không cần cái đầu tiên, mỗi thứ, nhưng chỉ cần một trong những thuộc tính của foo để tôi có thể làm việc với nó. Tôi chỉ cần một cái và không chắc có cách nào để lấy cái "đầu tiên" mà không sử dụng cho ... trong.
atogle

0

Sử dụng một mảng thay vì một đối tượng (dấu ngoặc vuông).

var example = [ {/* stuff1 */}, { /* stuff2 */}, { /* stuff3 */}];
var fist = example[0];

Lưu ý rằng bạn mất các định danh 'foo'. Nhưng bạn có thể thêm một thuộc tính tên cho các đối tượng được chứa:

var example = [ 
  {name: 'foo1', /* stuff1 */},
  {name: 'foo2', /* stuff2 */},
  {name: 'foo3', /* stuff3 */}
];
var whatWasFirst = example[0].name;

có những tình huống mà chúng ta không thể. Chúng tôi cho rằng chúng tôi không thể thay đổi sự thật rằng họ không ở trong một mảng
1mike12

1
Tôi nghĩ thật hữu ích khi đẩy lùi thiết kế một chút cho những độc giả có thể kiểm soát lược đồ JSON của họ. Về cơ bản, tôi đang mở rộng câu trả lời của Flavius ​​Stef bằng một số ví dụ.
hấp25


0

Bạn có thể sử dụng Object.prototype.keystrả về tất cả các khóa của một đối tượng theo cùng một thứ tự. Vì vậy, nếu bạn muốn đối tượng đầu tiên chỉ cần lấy mảng đó và sử dụng phần tử đầu tiên làm khóa mong muốn.

const o = { "key1": "value1", "key2": "value2"};
const idx = 0; // add the index for which you want value
var key = Object.keys(o)[idx];
value = o[key]
console.log(key,value); // key2 value2

1
Khi trả lời một câu hỏi cũ, câu trả lời của bạn sẽ hữu ích hơn nhiều cho những người dùng StackOverflow khác nếu bạn đưa vào một số ngữ cảnh để giải thích cách trả lời của bạn, đặc biệt đối với câu hỏi đã có câu trả lời được chấp nhận. Xem: Làm thế nào để tôi viết một câu trả lời tốt .
David Buck

0

chúng ta cũng có thể làm với sự chấp thuận này.

var example = {
  foo1: { /* stuff1 */},
  foo2: { /* stuff2 */},
  foo3: { /* stuff3 */}
}; 
Object.entries(example)[0][1];

0

Đây là một cách sạch hơn để có được khóa đầu tiên:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

var object2 = {
    needThis: 'This is a value of the property',
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

let [first] = Object.keys(example)
let [firstProp] = Object.keys(object2)

console.log(first)
//Prop : needThis, Value: This is a value of the property
console.log(`Prop : ${firstProp}, Value: ${object2[firstProp]}`)


Nhưng tại sao các mảng xung quanh [first]. Người dùng không yêu cầu một mảng như câu trả lời. Tại sao làm điều này trên first = Object.keys(example)[0]đó sẽ làm tương tự mà không cần phải bọc câu trả lời trong một mảng. Tại sao bạn sạch hơn xin vui lòng?
Michael Durrant

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.