2013-10-10 5 views

Odpowiedz

57

Nie można tego zrobić, gdy obiekt zostanie zamrożony, nie można go odmrozić.

Source

zamrażanie obiektu jest ostateczna forma zablokowanym. Po zamrożeniu obiektu nie można go odmrozić ani nie można nim manipulować w żaden sposób. Jest to najlepszy sposób, aby upewnić się, że obiekty pozostaną dokładnie tak, jak je w lewo, w nieskończoność

+7

Jest to poprawne pod względem technicznym, jeśli chodzi o mutowanie istniejącego obiektu. Możesz jednak skopiować/sklonować istniejący obiekt i zmutować jego właściwości teraz. Zobacz odpowiedź Andennoura TOUMI (http://stackoverflow.com/a/26752410/1251309), aby dowiedzieć się, jak to osiągnąć. –

+0

Byłoby SWEEEEET, gdyby obiekt mógł zostać odmrożony, o ile wywołanie unfreeze miało miejsce w tym samym zasięgu. Byłoby to OGROMNE oszczędzanie na wykorzystanie pamięci, aby uniknąć klonowania. f.e. 'Object.freeze (obj); thirdPartyRoutine (obj); Object.unfreeze (obj);/* kontynuuj używanie obj */' – trusktr

11

myślę, że można zrobić za pomocą kilku sztuczek:

  • najpierw utworzyć duplikat tymczasową zmienną oryginalny obiekt
  • następnie ustaw oryginalną zmienną na niezdefiniowaną
  • reset jej wartości z tymczasowego.

kod tutaj:

var obj = {a : 5}; 

console.log(obj); // {a: 5} 
Object.freeze(obj); 

obj.b = 10; // trying to add something to obj var 
console.log(obj); // output: {a: 5} -> means its frozen 

// Now use this trick 
var tempObj = {}; 
for(var i in obj){ 
    tempObj[i] = obj[i]; 
} 
console.log(tempObj); // {a: 5} 

// Resetting obj var 
obj = tempObj; 
console.log(obj);// {a: 5} 

obj.b = 10; // trying to add something to obj var 
console.log(obj); // output: {a: 5, b: 10} -> means it's not frozen anymore 

Uwaga: Należy pamiętać o jednej rzeczy, nie rób tempObj = obj, to nie będzie działać, ponieważ tempObj jest również zamrożone tam.

Fiddle tutaj: http://jsfiddle.net/mpSYu/

+1

poprawić widoczność: http://jsfiddle.net/abdennour/mpSYu/1/ –

+1

Rozumiem, do czego dążysz. Kopiowanie wartości jest sposobem "obejścia" zamrożenia obiektu, ale na końcu tego wszystkiego 'obj! = TempObj' - ich sygnatury nie są już takie same. – CodingIntrigue

+0

Ale zamrożony obiekt można usunąć! To może być na razie dopuszczalne rozwiązanie.Klonowanie zamrożonego obiektu i przypisanie do tego samego odniesienia, a następnie usunięcie zamrożonego spowoduje powrót do stanu starego, z tą tylko wadą tego klonowania ręcznie. Oczywiście straciliśmy oryginalną. –

8

przewodowy rozwiązanie :)

Object.unfreeze=function(o){ 
     var oo=undefined; 
     if(o instanceof Array){ 
       oo=[];var clone=function(v){oo.push(v)}; 
       o.forEach(clone); 
     }else if(o instanceof String){ 
      oo=new String(o).toString(); 
     }else if(typeof o =='object'){ 

     oo={}; 
     for (var property in o){oo[property] = o[property];} 


     } 
     return oo; 
} 

Best Practices:


var obj={a:1,b:2} 
// {a:1,b:2} 
    obj.c=3; 
    //{a:1,b:2,c:3} 
    Object.freeze(obj) 
    //{a:1,b:2,c:3} 
    obj.d=5; 
    //Error: Read only object 
    obj=Object.unfreeze(obj) 
    //{a:1,b:2,c:3} 
    obj.d=5; 
    //{a:1,b:2,c:3,d:5} 

var tab=[1,2,3] 
//[1,2,3] 
tab.push(4) 
//[1,2,3,4] 
Object.freeze(tab); 
//[1,2,3,4] 
tab.push(5) 
// Error : Ready only object 
tab=Object.unfreeze(tab); 
//[1,2,3,4] 
tab.push(9) 

//[1,2,3,4,9] 
+1

To powinna być zaakceptowana odpowiedź. Chociaż druga odpowiedź jest poprawna technicznie, realizuje to zadanie PO. –

+15

To się nie rozmraża, to kopiuje obiekt, zupełnie inna sprawa, –

+2

dla rekordu, wszystkie odpowiedzi na to pytanie są błędne i obejmują NOWĄ kopię, która obala wciąż nieruchomy obiekt ... – Leathan

1

Nie można odmrozić zamrożonego obiektu.

Można jednak zrobić to tak brzydkie biblioteki nie może zamarznąć coś w przyszłości, poprzez nadpisanie metody Object.freeze być no-op:

Object.freeze = function(obj) { return obj; }; // just return the original object 

W większości przypadków to wystarczy. Po prostu uruchom powyższy kod, zanim biblioteka zostanie załadowana, i nie może już niczego zamrozić. ;)

+0

Wydaje mi się to rozsądne, podobnie jak w przypadku odwróconej podkładki. Dlaczego zostało to odrzucone? – amay0048

+3

@ amay0048 Shim * dodaje * zachowanie. To * usuwa * istniejące zachowanie. To okropny pomysł i zdecydowanie nie powinien być stosowany w produkcji. 'Object.freeze' działa tak, jak robi to z jakiegoś powodu. – CodingIntrigue

+0

To okropny pomysł, aby użyć podkładki, która usuwa zachowanie podczas produkcji. z drugiej strony, jeśli chcesz hakować, możesz zrobić wszystko, co chcesz, aby osiągnąć swój cel. – mjz19910

1

Testowane FF 52:

miarę (symboliczne) „parent' przedmiotami w zamrożonej obiektu (gdzie jest symbolicznie odwołuje obok/oprócz innych symbolicznych odniesień w innych częściach kodu ten sam obiekt) NIE jest ZAMROŻONY (jak okno), można go usunąć przez operatora delete, - jak:

usunąć window.tinymce;

nawet jeśli okno.tinymce zostało zamrożone PRZED przez Object.freeze (window.tinymce); (inaczej "rodzic" stałby się czymś w rodzaju "zamrożonego" samego siebie, jako zawierającego niezniszczalne odniesienie do obiektu, które uczyniłoby symbol NIE-zamrożonego rodzica bez usunięcia ...)

Jako o ile ma się kopię/klon/rekonstrukcję/własną wersję/oryginalnego obiektu, który został już wykonany przed usunięciem/usunięciem, który pozbył się/nie ma/oryginalnych ograniczeń (zamrożenie, rozszerzalność, konfigurowalność, możliwość zapisu itd.), jeden może umieścić/przypisać odniesienie do tej kopii/klon/rekonstrukcja/własną wersję/do oryginalnego symbolicznego miejsca, - w ten sposób:

window.tinymce = the_copy_clone_reconstruction_own_version_object;

Upewnij się, że ten "copy_clone_reconstruction_own_version_object" w zasięgu globalnym nie został upuszczony po zakończeniu Twojego kodu obejścia! [W rzeczywistości sam obiekt powinien zostać usunięty/pamięć zwolniona/tylko i tylko wtedy, gdy ostatnie odniesienie do niego zostało usunięte z dowolnego zakresu, - jakiś czas później, z powodu-garbage collection, ale nie jestem pewien co do pierwszeństwo wyższa niż „funkcji wykończone - upuść wszystkich lokalnych vars”]

nie testowane: Inne odniesienia symboliczne może wskazywać na oryginalny, mrożone/ograniczony, obiekt Ponadto - jak coś, który został ustawiony jako

myobj.subobj = window.tinymce;

przed rozpoczęciem operacji.

Rzeczy takie jak to (myobj.subobj) prawdopodobnie (spróbują!) Ponadto wskazują zamrożony oryginał (?).

następne zdanie: NIE testowane!

Co należy użyć funkcji "proxy" do zawijania wartości-get/-set i innych zachowań (funkcji, ...) zamrożonego/zapieczętowanego lub w inny sposób ograniczonego (rozszerzalności, ...) obiektu? Utworzony w zakresie GLOBALNYM, taki jak p = nowy serwer proxy (target, handler); lub window.p = nowy serwer proxy (target, handler);
// gdzie obiekt docelowy jest obiektem do przechwytywania w celu przechwycenia/zahaczenia/monitorowania, jak na przykład "window.tinymce"

Dokument mdn dla proxy mówi, że ograniczenia (zamrożone, ...) Zapakowany obiekt jest traktowany, ale może odnosić się do samego obiektu podstawowego/oryginalnego (owinięty przez proxy) i może NIE odnosić się do naśladowania wykonanego przez proxy ...

Reguły zasięgu mogą zastosuj, jak wspomniano powyżej ...

Powiązane problemy