Dlaczego możemy usunąć niektóre wbudowane właściwości obiektu globalnego?

12

Czytam teraz es5 i stwierdzam, że atrybut [[konfigurowalny]] w niektórych wbudowanych właściwościach obiektu globalnego jest ustawiony na true, co oznacza, że ​​możemy usunąć te właściwości.

Na przykład:

metoda łączenia obiektu Array.prototype ma atrybuty

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

Możemy więc łatwo usunąć metodę łączenia dla Array, taką jak:

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

undefinedOstrzeżenie wyświetli się w moim chromie 17, firefox 9, tj. 10, a nawet ie6;

W Chrome 15 i Safari 5.1.1 atrybut [[konfigurowalny]] jest ustawiony na wartość true, a usunięcie wyniku jest również prawdą, ale wynik końcowy jest nadal function(){[native code]}. Wygląda na to, że jest to błąd i chrom go naprawia.

Nie zauważyłem tego wcześniej. Moim zdaniem usuwanie wbudowanych funkcji w kodzie użytkownika jest niebezpieczne i spowoduje wiele błędów podczas pracy z innymi. Dlaczego więc ECMAScript podejmuje taką decyzję?

demiks
źródło
Wiele odpowiedzi chwali możliwość dostosowania wbudowanej funkcjonalności poprzez usunięcie właściwości, ale takie podejście jest konieczne tylko dlatego, że funkcjonalność jest wbudowana w zmienne globalne zamiast używania DI. Wygląda na to, że dostosowywanie poprzez usunięcie właściwości to hack wokół zasadniczo złego projektu. Na przykład, jeśli chcesz zmienić parser JSON, możesz napisać kod, który pobiera parser JSON jako dane wejściowe.
Przywróć Monikę

Odpowiedzi:

2

Chciałbym się z tobą zgodzić, ale z drugiej strony właśnie znalazłem sytuację, w której musiałem, delete JSON.stringifyw pewnych okolicznościach, z powodu błędu w Firefoksie 3.5 . Z pewnością cieszyłem się z możliwości łatania tam wbudowanych małp.

N3dst4
źródło
Dlaczego po prostu tego nie zastąpisz?
demiksować
2
Ponieważ następną rzeczą, która się dzieje, jest ładowany plik JSON2.js, który wykrywa obecność JSON.stringifyi wstrzykuje go w razie potrzeby. Przepraszam, nie wyjaśniłem tego w mojej odpowiedzi.
N3dst4,
Możesz więc zmodyfikować również kod źródłowy JSON2.js, lol
demiksować 24.11.11
Zmodyfikowanie bibliotek firm zewnętrznych jest złym pomysłem, ponieważ wtedy nie można ich uaktualnić bez kopiowania wszystkich zmian.
N3dst4,
1

Konfigurowalne nie dotyczy usuwania.

Chodzi o możliwość zastąpienia wartości tylko do odczytu.

Jest to bardzo potężne narzędzie, a nieskonfigurowalne wartości są frustrujące, jeśli nie można ich usunąć.

Miałem całkiem sporo przypadków, w których musiałem naprawić niejasny błąd lub wprowadzić nieco inną funkcjonalność (przechwytywanie, logowanie). W tym celu należy wymienić wartość.

Przykład:

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

Cały pomysł polega na tym, że jeśli możesz usunąć właściwości, masz większą kontrolę nad meta programowaniem. Jeśli nie możesz ich usunąć, po prostu denerwujesz się tym językiem.

Nie ma dobrego powodu, aby uczynić właściwości nieusuwalnymi innymi niż denerwować ludzi.

Raynos
źródło
1
Atrybut [[zapisywalny]] kontroluje możliwość zmiany wartości. W ES5: [[Zapisywalny]] Boolean Jeśli jest fałszem, próby wykonania przez kod ECMAScript zmiany atrybutu [[Wartość]] przy użyciu [[Put]] nie powiodą się . [[Konfigurowalny]] Boolean Jeśli false, próba usunięcia właściwości, zmiana właściwości na właściwość akcesorium lub zmiana jego atrybutów (innych niż [[wartość]]) zakończy się niepowodzeniem.
demiksować
@demix Tak, zgadza się ...
Raynos
0

. usuwanie funkcji wbudowanych w kodzie użytkownika jest niebezpieczne

Wręcz przeciwnie. Zezwolenie na dostosowanie jest dobre, ponieważ pozwala autorom witryn na większą elastyczność.

Jeśli autor witryny musi załadować kod innej firmy w ramach tej samej maszyny wirtualnej JS i chce do tego użyć wbudowanego analizatora składni JS, zawsze może zabezpieczyć właściwości, ustawiając je na konfigurowalne przed załadowaniem kodu innej firmy.

Pacerier
źródło