Tại sao chúng ta có thể xóa một số thuộc tính tích hợp của đối tượng toàn cầu?


12

Tôi đang đọc es5 những ngày này và thấy rằng thuộc tính [[configureable]] trong một số thuộc tính tích hợp của đối tượng toàn cầu được đặt thành true, điều đó có nghĩa là chúng ta có thể xóa các thuộc tính này.

Ví dụ:

phương thức nối của đối tượng Array.prototype có các thuộc tính

{[[Writable]]:true, [[Enumerable]]: false, [[Configurable]]: true}

Vì vậy, chúng ta có thể dễ dàng xóa phương thức nối cho Array như:

delete Array.prototype.join;
alert([1,2,3].join);

Cảnh báo sẽ hiển thị undefinedtrong crom 17 của tôi, firefox 9, tức là 10, thậm chí tức là6;

Trong Chrome 15 & safari 5.1.1, thuộc tính [[có thể định cấu hình]] được đặt thành đúng và kết quả xóa cũng đúng nhưng kết quả cuối cùng vẫn là function(){[native code]}. Có vẻ như đây là một lỗi và crom sửa nó.

Tôi đã không nhận thấy điều đó trước đây. Theo tôi, xóa các hàm tích hợp trong mã của người dùng là nguy hiểm và sẽ phát sinh rất nhiều lỗi khi làm việc với người khác. Tại sao ECMAScript đưa ra quyết định này?


Nhiều câu trả lời khen ngợi khả năng tùy chỉnh chức năng tích hợp bằng cách xóa các thuộc tính nhưng cách tiếp cận này chỉ cần thiết vì chức năng này được gắn kết trong các biến toàn cục thay vì sử dụng DI. Có vẻ như tùy chỉnh bằng cách xóa các thuộc tính là một hack xung quanh một thiết kế xấu về cơ bản. Ví dụ: nếu bạn cần có thể thay đổi trình phân tích cú pháp JSON, bạn có thể viết mã lấy trình phân tích cú pháp JSON làm đầu vào.
Phục hồi Monica

Câu trả lời:


2

Tôi có xu hướng đồng ý với bạn, nhưng mặt khác tôi chỉ tìm thấy một tình huống mà tôi cần delete JSON.stringifytrong một số trường hợp nhất định vì một lỗi trong Firefox 3.5 . Tôi chắc chắn rất vui vì khả năng dựng khỉ ở đó.


Tại sao bạn không ghi đè lên nó?
demix

2
Bởi vì điều tiếp theo xảy ra là JSON2.js được tải, phát hiện sự hiện diện JSON.stringifyvà tiêm nó nếu cần thiết. Xin lỗi, tôi đã không giải thích điều đó trong câu trả lời của tôi.
N3dst4

Vì vậy, bạn cũng có thể sửa đổi mã nguồn của JSON2.js, lol
demix

Đó là một ý tưởng tồi để sửa đổi thư viện của bên thứ ba vì sau đó bạn không thể nâng cấp chúng mà không sao chép tất cả các thay đổi của mình.
N3dst4

1

Cấu hình không phải là về xóa.

Đó là về khả năng thay thế một giá trị chỉ đọc.

Đây là một công cụ rất mạnh và các giá trị không thể định cấu hình sẽ gây khó chịu nếu bạn không thể xóa chúng.

Tôi đã có khá nhiều trường hợp cần sửa một lỗi tối nghĩa hoặc tiêm một chút chức năng khác nhau (chặn, ghi nhật ký). Làm điều đó đòi hỏi phải thay thế giá trị.

Thí dụ:

Object.defineProperty(Object.prototype, "foo", {
  value: 42,
  configurable: true
});

var o = {};
o.foo = 50; // fails. foo is not writable
delete Object.prototype.foo;
o.foo = 50; // succeeds
/* optionally put Object.prototype.foo back */

Toàn bộ ý tưởng là nếu bạn có thể xóa các thuộc tính, bạn có nhiều quyền kiểm soát lập trình meta hơn. Nếu bạn không thể xóa chúng thì bạn sẽ cảm thấy khó chịu với ngôn ngữ này.

Không có lý do chính đáng để làm cho các tài sản không thể xóa khác sau đó để làm phiền mọi người.


1
Thuộc tính [[writable]] kiểm soát khả năng thay đổi giá trị. Trong ES5: [[Writable]] Boolean Nếu sai, cố gắng bằng mã ECMAScript để thay đổi thuộc tính [[Value]] của thuộc tính bằng [[Put]] sẽ không thành công . [[Có thể cấu hình]] Boolean Nếu sai, cố gắng xóa thuộc tính, thay đổi thuộc tính thành thuộc tính của người truy cập hoặc thay đổi thuộc tính của nó (trừ [[Giá trị]]) sẽ không thành công.
demix

@demix Vâng, điều đó đúng ...
Raynos

0

Các chức năng tích hợp sẵn trong mã người dùng rất nguy hiểm

Hoàn toàn ngược lại. Cho phép tùy chỉnh là tốt vì nó cho phép các tác giả trang web có sự linh hoạt hơn.

Nếu tác giả trang web cần tải mã bên thứ 3 trong cùng một VM VM muốn sử dụng trình phân tích cú pháp JS sẵn có để làm như vậy, anh ta luôn có thể bảo mật các thuộc tính bằng cách đặt chúng thành không thể định cấu hình trước khi tải mã bên thứ 3.

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.