Почему мы можем удалить некоторые встроенные свойства глобального объекта?

12

В эти дни я читаю es5 и нахожу, что атрибут [[configurable]] в некоторых встроенных свойствах глобального объекта имеет значение true, что означает, что мы можем удалить эти свойства.

Например:

метод соединения объекта Array.prototype имеет атрибуты

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

Таким образом, мы можем легко удалить метод соединения для Array, например:

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

Предупреждение будет отображаться undefinedв моем chromium 17, firefox 9, то есть 10, даже ie6;

В Chrome 15 и Safari 5.1.1 атрибут [[configurable]] имеет значение true, и результат удаления также равен true, но окончательный результат остается function(){[native code]}. Похоже, это ошибка, и хром исправит ее.

Я не заметил этого раньше. На мой взгляд, удаление встроенных функций в коде пользователя опасно и может вызвать столько ошибок при работе с другими. Так почему ECMAScript принимает это решение?

Demix
источник
Многократные ответы хвалят способность настраивать встроенную функциональность, удаляя свойства, но этот подход необходим только потому, что функциональность встроена в глобальные переменные вместо использования DI. Кажется, что настройка путем удаления свойств - это взлом вокруг принципиально плохого дизайна. Например, если вам нужно изменить синтаксический анализатор JSON, вы можете написать код, который принимает анализатор JSON в качестве входных данных.
Восстановить Монику

Ответы:

2

Я склонен был бы согласиться с вами, но с другой стороны, я просто нашел ситуацию, в которой мне было необходимо delete JSON.stringifyпри определенных обстоятельствах из-за ошибки в Firefox 3.5 . Я, конечно, был рад возможности встроить туда обезьян-патч.

N3dst4
источник
Почему бы тебе просто не переопределить это?
Демикс 24.11.11
2
Потому что следующее, что происходит, - это загружаемый файл JSON2.js, который обнаруживает присутствие JSON.stringifyи внедряет его при необходимости. Извините, я не объяснил это в своем ответе.
N3dst4
Таким образом, вы также можете изменить исходный код JSON2.js, lol
demix
Плохо изменять сторонние библиотеки, потому что тогда вы не сможете обновить их, не скопировав все свои изменения.
N3dst4
1

Настраиваемый не об удалении.

Речь идет о возможности заменить значение только для чтения.

Это очень мощный инструмент, и ненастраиваемые значения расстраивают, если вы не можете их удалить.

У меня было довольно много случаев, когда мне нужно было исправить непонятную ошибку или добавить немного другую функциональность (перехват, ведение журнала). Для этого необходимо заменить значение.

Пример:

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 */

Идея заключается в том, что если вы можете удалить свойства, у вас будет больше метапрограммирующего контроля Если вы не можете удалить их, вы будете просто раздражены на языке.

Нет веских причин делать свойства не удаляемыми, кроме как раздражать людей.

Raynos
источник
1
Атрибут [[writable]] контролирует возможность изменения значения. В ES5: [[Writable]] Boolean Если false, попытки с помощью кода ECMAScript изменить атрибут [[Value]] свойства с помощью [[Put]] не будут выполнены . [[Configurable]] Boolean Если false, попытка удалить свойство, изменить свойство на свойство доступа или изменить его атрибуты (кроме [[Value]]) не удастся.
Демикс 24.11.11
@demix Да, это правильно ...
Райнос
0

.. Удалить встроенные функции в коде пользователя опасно

Наоборот. Разрешить настройку хорошо, потому что она позволяет авторам веб-сайтов иметь большую гибкость.

Если автору веб-сайта необходимо загрузить сторонний код в той же виртуальной машине JS и для этого использовать встроенный JS-анализатор, он всегда может защитить свойства, установив их в неконфигурируемые перед загрузкой стороннего кода.

Pacerier
источник