IT TIP

JavaScript에서 Object.freeze 또는 Object.seal의 반대

itqueen 2020. 12. 15. 20:37
반응형

JavaScript에서 Object.freeze 또는 Object.seal의 반대


Object.freeze또는 의 반대는 무엇입니까 Object.seal? 분리와 같은 이름을 가진 함수가 있습니까?


이렇게 할 수있는 방법이 없습니다. 일단 개체가 고정되면 고정을 해제 할 방법이 없습니다.

출처

객체를 고정하는 것은 궁극적 인 잠금 방식입니다. 일단 개체가 고정되면 고정 해제 할 수 없으며 어떤 방식으로도 변경할 수 없습니다. 이것은 객체가 남겨진 그대로, 무기한 그대로 유지되도록하는 가장 좋은 방법입니다.


몇 가지 트릭을 사용하여 할 수 있다고 생각합니다.

  • 먼저 원본 개체의 중복 임시 변수를 만듭니다.
  • 그런 다음 원래 변수를 정의되지 않음으로 설정하십시오.
  • 임시에서 그것의 값을 재설정합니다.

여기에 코드 :

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

참고 : 한 가지 명심하십시오.하지 마십시오 tempObj = obj. 그러면 작동하지 않습니다 tempObj.

여기 바이올린 : http://jsfiddle.net/mpSYu/


유선 솔루션 :)

 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;
 }

모범 사례 :


 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]

고정 된 개체는 고정 해제 할 수 없습니다.

그러나 Object.freeze 메서드를 no-op으로 재정 의하여 성가신 라이브러리가 앞으로 아무것도 고정 할 수 없도록 만들 수 있습니다.

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

대부분의 경우 이것으로 충분합니다. 라이브러리가로드되기 전에 위의 코드를 실행하면 더 이상 아무것도 고정 할 수 없습니다. ; )


FF 52에서 테스트 됨 :

고정 된 개체의 (기호) '부모'개체 (동일한 개체에 대한 코드의 다른 부분에서 다른 기호 참조에 의해 기호 적으로 참조되는 경우)가 고정되지 않는 한 (예 : 창) 그럼에도 불구하고 delete-operator에 의해 삭제하십시오.

window.tinymce 삭제;

even if window.tinymce had been frozen BEFORE by Object.freeze(window.tinymce); (otherwise the 'parent' would become some kind of "frozen" itself, as containing a non-destroyable object-reference, that would make the symbol of the NOT-frozen parent un-deletable ...)

As far as one has a copy/clone/reconstruction/own version/ of the original object already made before deletion/removal, which got rid/has none/ of the original restrictions (frozen, extensibility, configurability, writeability and so on), one can put/assign a reference to that copy/clone/reconstruction/own version/ to the original symbolic place, - like that way:

window.tinymce = the_copy_clone_reconstruction_own_version_object;

Make sure to have that "copy_clone_reconstruction_own_version_object" in the global scope for not being dropped after Your workaround-code has finished! [Actually the object itself should be dropped/it's memory freed/ just and only when the very last reference to it has been removed from any scope, - some time later, due to-garbage collection, but I'm not sure about the precedence higher than the 'function finished - drop all local vars']

NOT tested: Other symbolic references MAY point to the original, frozen/restricted, object furthermore, - like something, which was set as

myobj.subobj=window.tinymce;

before Your operations began.

Stuff like that (myobj.subobj) will probably (give it a try!) furthermore point to the frozen original (?).

next notion: NOT tested!

What about to use the 'proxy'-feature to wrap value-get/-set and other behaviour (functions, ...) of a frozen/sealed or otherwise restricted (extensibility, ...) object? Created at GLOBAL scope like p = new Proxy(target, handler); or window.p = new Proxy(target, handler);
// where target is the object to wrap for interception/hooking/monitoring, as for instance "window.tinymce"

The mdn-doc for the proxy-topic says, that restrictions (frozen, ...) of the wrapped object are kept regarded, but that could refer to the core-/original-object itself (wrapped by the proxy) and might eventually NOT refer to the mimic made by the proxy ...

Scope-rules might apply as mentioned above ...


You cannot unfreeze (thaw) an object, but if the object is simply a collection of primitives (no functions or classes), you can get a thawed clone of the object like this:

const unfrozenObj = JSON.parse(JSON.stringify(frozenObj));

You can unfreeze an array by using spread operator.

//let suppose arr is a frozen array i.e. immutable
var arr = [1, 2, 3];

//if arr is frozen arr you cannot mutate any array referring to it
var temp = arr;

temp.push(4);  //throws an error "Cannot modify frozen array elements"

//here mutableArr gets the elements of arr but not reference to it
//hence you can mutate the mutableArr

var mutableArr = [...arr];

mutableArr.push(4);  //executes successfully 

I was issue that problem too. TO fix it, I used JavaScript JSON API to unfreeze my object: const unfreezeObject = JSON.parse(JSON.stringify(freezeObject)). After, I did all mutations I needed.

ReferenceURL : https://stackoverflow.com/questions/19293321/opposite-of-object-freeze-or-object-seal-in-javascript

반응형