Чому ми можемо видалити деякі вбудовані властивості глобального об’єкта?


12

Я читаю es5 в наші дні і знаходжу, що атрибут [[configableble]] у деяких вбудованих властивостях глобального об'єкта встановлено на true, що означає, що ми можемо видалити ці властивості.

Наприклад:

метод приєднання об'єкта Array.prototype має атрибути

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

Таким чином, ми можемо легко видалити метод з'єднання для масиву, наприклад:

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

Повідомлення відображатиметься undefinedв моїй хромовій 17, Firefox 9, тобто 10, навіть 6;

У Chrome 15 & safari 5.1.1 атрибут [[налаштовується]] встановлено на істинне, а результат видалення також є істинним, але остаточний результат все-таки є function(){[native code]}. Схоже, це помилка, і хром її виправляє.

Я цього раніше не помічав. На мою думку, видалити вбудовані функції в коді користувача небезпечно і виведе так багато помилок при роботі з іншими. Отже, чому ECMAScript приймає таке рішення?


Кілька відповідей хвалить можливість налаштувати вбудовану функціональність, видаляючи властивості, але такий підхід необхідний лише тому, що функціональність вбудована в глобальні змінні замість використання DI. Здається, що налаштування за допомогою видалення властивостей є злому навколо принципово поганого дизайну. Наприклад, якщо вам потрібно мати можливість змінити аналізатор JSON, ви можете написати код, який приймає аналізатор JSON.
Відновіть Моніку

Відповіді:


2

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


Чому б ти просто не перекрив це?
демікс

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 Якщо помилково, спроби коду ECMAScript змінити атрибут [[Value]] властивості за допомогою [[Put]] не вдасться . [[Configurable]] Boolean Якщо помилкова, спроба видалити властивість, змінити властивість, що є власністю доступу, або змінити його атрибути (крім [[Значення]]) не вдасться.
демікс

@demix Так, це правильно ...
Raynos

0

..використовувати вбудовані функції в код користувача небезпечно

Зовсім навпаки. Дозволити налаштування добре, оскільки дозволяє авторам веб-сайтів мати більшу гнучкість.

Якщо автору веб-сайту потрібно завантажити код сторонньої сторони в той же JS VM і бажає використовувати вбудований JS-аналізатор для цього, він завжди може захистити властивості, встановивши їх на неконфігурувані перед завантаженням коду сторонніх сторін.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.