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


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.