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


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 принимает это решение?


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

Ответы:


2

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


Почему бы тебе просто не переопределить это?
— Демикс 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 */

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

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


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

@demix Да, это правильно ...
— Райнос

0

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.