2015-03-14 17 views
5

tính cấu hình dường như deletable:Tại sao thuộc tính có thể định cấu hình này không thể xóa?

var o = {}; 
Object.defineProperty(o, 'prop', { 
    configurable: true, 
    value: 'val' 
}); 
delete o.prop; // true 
o.prop;  // undefined 

Nhưng nó không hoạt động trong trường hợp sau đây, ít nhất là trên Firefox và Chrome:

var form = document.createElement('form'), 
    input = document.createElement('input'); 
form.appendChild(input); 
var elems = form.elements; 
Object.getOwnPropertyDescriptor(form, 0) 
     .configurable; // true <────────────────────── !!! 
delete elems[0];  // false       │ 
elems[0];   // input       │ 
(function(){ 'use strict'; //       V 
    delete elems[0]; // TypeError: property 0 is non-configurable 
})();    // and can't be deleted 

Nhưng điều này dường như mâu thuẫn với spec.

Nhà điều hành delete được định nghĩa như thế này:

11.4.1 - The delete Operator

Việc sản xuất UnaryExpression: deleteUnaryExpression được đánh giá như sau:

Vì vậy, kết quả của việc sử dụng delete phụ thuộc vào [[Xóa]]. Bây giờ chúng ta hãy xem những gì [[Xóa]] làm:

8.12.7 - [[Delete]] (P, Throw)

Khi [[Xóa]] phương pháp nội bộ của O được gọi với tài sản tên P và cờ Boolean Ném, các bước sau đây được thực hiện:

  • Hãy desc là kết quả của cách gọi [[GetOw nProperty]] phương thức nội bộ của O với tên thuộc tính P.
  • Nếu descundefined, sau đó trả lại đúng.
  • Nếu desc.[[Cấu hình]] là đúng, sau đó
    • Di chuyển tài sản riêng với tên P từ O.
    • Trả lại đúng.
  • khác nếu Ném, sau đó ném một TypeError ngoại lệ.
  • Trả lại false.

Do đó, nếu thuộc tính được cấu hình, nó sẽ bị xóa.

Nhưng chờ đợi, có thể Object.getOwnPropertyDescritor là một troll và nói rằng thuộc tính có thể định cấu hình, nhưng [[Configurable]] là false. Hãy xem:

15.2.3.3 - Object.getOwnPropertyDescriptor (O, P)

Khi getOwnPropertyDescriptor hàm được gọi, các bước sau đây được thực hiện:

  • Nếu Type (O) không được đối tượng ném một TypeError ngoại lệ.
  • Hãy để tênToString (P).
  • Hãy desc là kết quả của cách gọi [[GetOwnProperty]] phương pháp nội bộ của O với lập luận tên.
  • Trả lại kết quả gọi số FromPropertyDescriptor (desc).

Vì vậy, nó cũng sử dụng [[GetOwnProperty]], như [[Xóa]]. Có lẽ troll là FromPropertyDescriptor?

8.10.4 FromPropertyDescriptor (Desc)

Khi FromPropertyDescriptor hoạt động trừu tượng được gọi với mô tả tài sản quyết, các bước sau đây được thực hiện:

  • Nếu quyếtkhông xác định, sau đó trở không xác định.
  • Hãy obj thể là kết quả của việc tạo ra một đối tượng mới, nếu như bởi sự biểu hiện new Object() nơi Object là tiêu chuẩn được xây dựng trong constructor với tên đó.
  • ...
  • Gọi [[DefineOwnProperty]] phương pháp nội bộ của obj với đối số "configurable", Property Descriptor {[[Giá trị]]:. quyết [[Cấu hình]], [[Có thể ghi được ]]: đúng, [[Enumerable]]: đúng, [[Cấu hình]]: đúng}, và sai.
  • Trả lại obj.

Vì vậy, không, nó không phải là troll. Thuộc tính configurable của bộ mô tả thuộc tính được đặt thành giá trị [[Có thể cấu hình]].

Làm cách nào để có thể xóa thuộc tính có thể định cấu hình?

Trả lời

3

Các thuộc tính có thể định cấu hình có hiệu lực sẽ bị xóa.

Nhưng có một vấn đề lớn: chỉ áp dụng cho native objects, nhưng không áp dụng cho host objects.

Như đã giải thích trong 8.6.2 - Object Internal Properties and Methods,

vật chủ có thể hỗ trợ những tính chất nội bộ với bất kỳ hành vi thực hiện phụ thuộc vào miễn là nó phù hợp với các hạn chế đối tượng máy chủ cụ thể được nêu trong tài liệu này.

Đối với những người, [[GetOwnProperty]] phải hành xử khác nhau:

Nếu một tài sản được mô tả như một thuộc tính dữ liệu và nó có thể trở giá trị khác nhau theo thời gian, sau đó một trong hai hoặc cả hai [ [Ghi được]] Các thuộc tính và [[Có thể cấu hình]] phải là đúng ngay cả khi không có cơ chế để thay đổi giá trị được hiển thị thông qua các phương pháp nội bộ khác.

Trong ví dụ của bạn, form.elements là một cá thể HTMLFormControlsCollection được xác định bởi thông số HTML, do đó, nó là đối tượng lưu trữ.

Do đó, tình hình là

  • Nó có một tùy chỉnh [[GetOwnProperty]] mà nói rằng tài sản '0' là cấu hình bởi vì giá trị của nó có thể thay đổi.
  • Nó cũng có [[Xóa]] tùy chỉnh không xóa thuộc tính, ngay cả khi [[GetOwnProperty]] cho biết cấu hình có thể định cấu hình.
Các vấn đề liên quan