Vô số có nghĩa là gì?


151

Tôi đã được chuyển đến trang MDN for..in khi nó nói, "for..in lặp lại các thuộc tính vô số của một đối tượng."

Sau đó, tôi đã đi đến trang Vô số và quyền sở hữu các thuộc tính với thông báo "Vô số thuộc tính là những thuộc tính có thể được lặp lại bởi một vòng lặp for..in."

Từ điển định nghĩa vô số là có thể đếm được, nhưng tôi thực sự không thể hình dung được điều đó có nghĩa là gì. Tôi có thể lấy một ví dụ về một cái gì đó là vô số?


Bạn có hiểu những gì for-inkhông?

Từ các câu trả lời tôi đã nhận được rằng..tôi cho phép tất cả các thuộc tính có thể đếm được của một đối tượng có sẵn để sử dụng với câu lệnh for
Patrick

6
Ý nghĩa đơn giản nhất là: liệu một tài sản sẽ được sản xuất bởi một for invòng lặp hay không (đối với những người không muốn biết chi tiết hoặc chỉ không quan tâm;))
Tomasz Racia

Câu trả lời:


158

Một thuộc tính vô số là một thuộc tính có thể được bao gồm trong và truy cập trong for..incác vòng lặp (hoặc một lần lặp tương tự của các thuộc tính, như Object.keys()).

Nếu một thuộc tính không được xác định là có thể đếm được, vòng lặp sẽ bỏ qua rằng nó nằm trong đối tượng.

var obj = { key: 'val' };

console.log('toString' in obj); // true
console.log(typeof obj.toString); // "function"

for (var key in obj)
    console.log(key); // "key"

Một thuộc tính được xác định là vô số hoặc không [[Enumerable]]thuộc tính của chính nó . Bạn có thể xem đây là một phần của mô tả của tài sản :

var descriptor = Object.getOwnPropertyDescriptor({ bar: 1 }, 'bar');

console.log(descriptor.enumerable); // true
console.log(descriptor.value);      // 1

console.log(descriptor);
// { value: 1, writable: true, enumerable: true, configurable: true }

Một for..invòng lặp sau đó lặp qua tên thuộc tính của đối tượng.

var foo = { bar: 1, baz: 2};

for (var prop in foo)
    console.log(prop); // outputs 'bar' and 'baz'

Nhưng, chỉ đánh giá tuyên bố của nó - console.log(prop);trong trường hợp này - cho những thuộc tính có [[Enumerable]]thuộc tính true.

Điều kiện này được đặt ra vì các đối tượng có nhiều thuộc tính hơn , đặc biệt là từ thừa kế :

console.log(Object.getOwnPropertyNames(Object.prototype));
// ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", /* etc. */]

Mỗi thuộc tính này vẫn tồn tại trên đối tượng :

console.log('constructor' in foo); // true
console.log('toString' in foo);    // true
// etc.

Nhưng, họ bị bỏ qua bởi for..invòng lặp bởi vì họ không thể đếm được.

var descriptor = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor');

console.log(descriptor.enumerable); // false

Vì vậy, thuộc tính constructor là không thể đếm được vì nó không hiển thị trong vòng lặp for..in. Trong khi tên của các thuộc tính như bar hoặc baz là vô số vì bạn có thể console.log mỗi cái từ đối tượng?
Patrick

5
Điều này không hoàn toàn chính xác : But, they are skipped (or not counted) by the for..in loop because they are not enumerable. Các thuộc tính trên Object.prototypethực tế bị bỏ qua vì chúng tiếp tục lên chuỗi nguyên mẫu, không phải vì chúng không thể đếm được. Không getOwnPropertyNames()hoặc keys()hiển thị các thuộc tính không phải là của riêng đối tượng. Một lưu ý phụ, đúng là nhiều thuộc tính tích hợp không thể đếm được và do đó sẽ không hiển thị keys(), nhưng bạn sẽ phải viết thêm mã nếu bạn muốn duyệt qua chuỗi nguyên mẫu.
Magnus

theo nghĩa đen, vô số có nghĩa là có thể đếm được
Christian Matthew

49

Nếu bạn tạo một đối tượng thông qua myObj = {foo: 'bar'}hoặc một cái gì đó ở đó, tất cả các thuộc tính là vô số. Vì vậy, câu hỏi dễ dàng hơn là, những gì không thể đếm được? Một số đối tượng nhất định có một số thuộc tính không thể đếm được, ví dụ nếu bạn gọi Object.getOwnPropertyNames([])(trả về một mảng của tất cả các thuộc tính, có thể đếm được hoặc không, trên []), nó sẽ trả về ['length'], bao gồm thuộc tính không thể đếm được của một mảng, 'length' .

Bạn có thể tạo các thuộc tính không thể đếm được bằng cách gọi Object.defineProperty:

var person = { age: 18 };
Object.defineProperty(person, 'name', { value: 'Joshua', enumerable: false });

person.name; // 'Joshua'
for (prop in person) {
  console.log(prop);
}; // 'age'

Ví dụ này mượn rất nhiều từ các thuộc tính Không thể đếm được trong JavaScript , nhưng cho thấy một đối tượng đang được liệt kê. Các thuộc tính có thể hoặc không thể ghi, cấu hình hoặc liệt kê. John Resig thảo luận về vấn đề này trong phạm vi Đối tượng và Thuộc tính của ECMAScript 5 .

Và, có một câu hỏi về Stack Overflow về lý do tại sao bạn muốn biến các thuộc tính thành không thể đếm được .


Hừm, cả upvote và downvote. Chắc chắn, nếu có bất cứ điều gì về câu trả lời này đáng để bỏ qua, xin vui lòng thêm một nhận xét ở đây.
Carpeliam

1
Một câu trả lời khác đã viết điều này: var o = {}; o ['foo'] = 0; // liệt kê, bình thường Object.defineProperty (o, 'bar', {value: 1}); // không thể đếm được, lạ Tại sao lại thêm vô số: false?
Patrick

5
@Patrick, tôi đã đưa nó vào đây một phần để rõ ràng từ ví dụ rằng đó là một tùy chọn, nhưng tùy thuộc vào đối tượng của bạn, việc rõ ràng có thể là một quyết định chắc chắn để mọi người đọc mã của bạn rõ ràng.
Carpeliam

@carpeliam Cảm ơn lời giải thích ngắn gọn và rất rõ ràng này, tôi không thể nhận được câu trả lời cho đến khi tôi đi qua câu trả lời của bạn: D
sandeepKumar

37

Nó nhàm chán hơn nhiều so với những thứ nên được hình dung.

Có nghĩa đen là một thuộc tính trên tất cả các thuộc tính được gọi là "liệt kê." Khi nó được đặt thành false, for..inphương thức sẽ bỏ qua thuộc tính đó, giả vờ nó không tồn tại.

Có rất nhiều thuộc tính trên các đối tượng có "vô số" được đặt thành false, như "valueOf" và "hasOwnProperty", vì cho rằng bạn không muốn công cụ JavaScript lặp lại các đối tượng đó.

Bạn có thể tạo các thuộc tính không thể đếm được của riêng mình bằng Object.definePropertyphương thức:

  var car = {
    make: 'Honda',
    model: 'Civic',
    year: '2008',
    condition: 'bad',
    mileage: 36000
  };

  Object.defineProperty(car, 'mySecretAboutTheCar', {
    value: 'cat pee in back seat',
    enumerable: false
  });

Bây giờ, thực tế là thậm chí có một bí mật về chiếc xe được giấu kín. Tất nhiên họ vẫn có thể truy cập trực tiếp vào tài sản và nhận được câu trả lời:

console.log(car.mySecretAboutTheCar); // prints 'cat pee in back seat'

Nhưng, họ sẽ phải biết rằng tài sản tồn tại trước tiên, bởi vì nếu họ cố gắng truy cập thông qua for..inhoặc Object.keysnó sẽ hoàn toàn bí mật:

console.log(Object.keys(car)); //prints ['make', 'model', 'year', 'condition', 'mileage']

Họ nên gọi nó là "forInAble."


5
Được nâng cấp cho dòng cuối cùng đó - Tôi nghĩ rằng nếu nó thực sự đã được gọi là forAble thì sẽ không có ai hỏi về nó cả. Mà sẽ trả về câu hỏi của tôi - tại sao sẽ bạn (hoặc tại sao bạn phải) thiết lập một tài sản để không đếm được? Thuộc tính độ dài của một mảng được sử dụng khá thường xuyên như một ví dụ về thuộc tính không thể đếm được, nhưng tại sao bạn không thể đặt nó thành vô số (ý tôi không phải là hạn chế JavaScript, tại sao nó lại được đặt thành không thể đếm được trong JavaScript nơi đầu tiên)?
Chris

Để làm rõ câu hỏi của tôi, tại sao quyết định sau đây không phải là một lựa chọn: thực hiện: Mô hình Honda: Bí mật công dân: Chiều dài
Chris

Hmmm ... tôi có thể đã tìm thấy câu trả lời cho câu hỏi của riêng tôi. Từ một tìm kiếm google cho "Ý bạn là gì khi liệt kê các loại dữ liệu?" Dữ liệu liệt kê có một bộ giá trị hữu hạn. Một kiểu dữ liệu liệt kê bao gồm các giá trị mà bạn cho phép cho kiểu đó hoặc các giá trị được liệt kê. Đối với các kiểu liệt kê dựa trên số nguyên, mỗi giá trị liệt kê bao gồm một tên và một giá trị số cơ bản. Vì vậy, nếu tôi hiểu chính xác, vì có vô số độ dài có thể, bạn sẽ phải gán một số lượng vô hạn các tên, một tên đến từng chiều dài. Đúng không?
Chris

Chà, giải quyết câu hỏi đầu tiên của bạn, đặt một thuộc tính không thể đếm được trên một đối tượng là một chút hack, vì cách duy nhất bạn có thể tìm ra những gì trên đối tượng đó sẽ là xem mã và làm cơ sở mã phát triển nó có thể được chôn cất. Vì vậy, nói chung, bạn sẽ không muốn sử dụng nó. Về '.length' cung cấp số lượng ký tự trong một chuỗi hoặc các phần tử trong một mảng chỉ là thứ được cho là chúng tôi sẽ không muốn đưa vào nếu chúng tôi sử dụng 'cho ... trong.' Không thể trả lời tại sao các vị thần của Js lại làm theo cách đó nhất thiết. Họ có lý do ( ahem ) ý kiến ​​vượt quá sự hiểu biết của chúng tôi.
Gabriel Kunkel

... và tôi không nghĩ rằng tôi có thể trả lời câu hỏi thứ hai của bạn về các loại dữ liệu được liệt kê, mặc dù nó trông giống như một cái gì đó tôi có thể nhai trong một lúc khá lâu nếu tôi có thời gian. :-)
Gabriel Kunkel

9

Nếu bạn gặp khó khăn trong việc hình dung "nó có nghĩa là gì?" Tại sao không tự hỏi, nó có nghĩa là không thể đếm được ?

Tôi nghĩ về nó một chút như thế này, một nonenumerable tài sản tồn tại nhưng là một phần ẩn ; điều đó có nghĩa là đếm được là kỳ lạ. Bây giờ bạn có thể tưởng tượng vô số là những gì còn lại - tài sản tự nhiên hơn mà chúng ta đã từng gặp phải kể từ khi chúng tôi phát hiện ra Đối tượng . Xem xét

var o = {};
o['foo'] =  0;                               // enumerable, normal
Object.defineProperty(o, 'bar', {value: 1}); // nonenumerable, weird

Bây giờ trong một for..in , hãy tưởng tượng nó như mã giả

for property in o:
    if not property enumerable continue // skip non-enumerable, "bar"
    else do /* whatever */              // act upon enumerable, "foo"

nơi phần thân của vòng lặp bạn đã nhập JavaScript nằm ở vị trí của/* whatever */


8

Tôi sẽ viết định nghĩa một dòng của ENUMERABLE

Enumerable: Chỉ định xem thuộc tính có thể được trả về trong vòng lặp for / in hay không.

var obj = {};
Object.defineProperties(obj, {
    set1: {enumerable: true},
    set2: {enumerable: false},
});
Object.keys(obj); // ["set1"]
Object.getOwnPropertyNames(obj); // ["set1", "set2"]

0

phương pháp không phải là vô số; hay đúng hơn là xây dựng trong phương pháp này không .. tho sau khi tìm kiếm trên những gì đếm được phương tiện để kịch bản java; nó chỉ đề cập đến một thuộc tính thuộc tính .. tất cả các đối tượng được tạo trong ecma3 là vô số, và bây giờ ecma5 bạn có thể định nghĩa nó .... đó là nó ..: D lol đã cho tôi một chút để tìm câu trả lời; nhưng tôi tin rằng nó đã được nói đến trong cuốn sách của David Flanagan .. vì vậy tôi đoán nó có nghĩa là "ẩn" hoặc không "ẩn" trong các phương thức đó không được hiển thị trong vòng lặp for, và do đó là "ẩn"


0

Hãy nghĩ về kiểu dữ liệu enum, chỉ là một cấu trúc của các đối tượng tương ứng với các số khác nhau. Để khai báo một cái gì đó là vô số là khai báo rằng nó tương ứng với một số cụ thể, cho phép nó được đặt một vị trí trong Từ điển đại diện cho các thành phần có thể đếm được của một đối tượng. Nói một cách đơn giản, làm cho một đối tượng được liệt kê giống như nói với trình biên dịch, "Này, thuộc tính này, tôi muốn thấy điều này khi tôi kiểm tra dữ liệu về đối tượng này."


0

Các phương thức dựng sẵn mà các đối tượng kế thừa không thể đếm được, nhưng các thuộc tính mà mã của bạn thêm vào các đối tượng là vô số trừ khi được quy định rõ ràng

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.