与JavaScript中的Object.freeze或Object.seal相反

Abd*_*UMI 57 javascript locking freeze

Object.freeze或者相反的是Object.seal什么?是否有一个具有诸如分离之类的名称的功能?

Cod*_*gue 82

没有办法做到这一点,一旦一个物体被冻结,就无法解冻它.

资源

冻结物体是锁定的最终形式.一旦物体被冻结,它就不会被解冻 - 也不会以任何方式被篡改.这是确保您的对象无限期地保持与您离开它们的最佳方式

  • 就改变现有对象而言,这在技术上是正确的.但是,您可以复制/克隆现有对象并立即改变其属性.请参阅Andennour TOUMI(http://stackoverflow.com/a/26752410/1251309)的答案,了解如何完成此任务. (9认同)
  • 对于同一范围内的冻结和解冻,“冻结”(锁定)函数还可以返回“解冻”(解锁)它所需的“密钥”。 (5认同)
  • 可能是为了安全问题?如果您有一个不希望任何人接触的全局对象,该怎么办。如果潜在的黑客可以执行 Object.unfreeze(obj) 并绕过它,那么冻结它们将毫无意义。 (3认同)
  • 只要解冻调用发生在同一范围内,如果对象可以解冻,那将是SWEEEEET.这将大大节省内存使用量,以避免克隆.fe`Object.freeze(obj); thirdPartyRoutine(OBJ); Object.unfreeze(OBJ);/*继续使用obj*/` (2认同)

Ash*_*mar 14

我认为你可以做一些技巧:

  • 首先创建一个原始对象的重复临时变量
  • 然后将原始变量设置为undefined
  • 从临时重置它的值.

代码在这里:

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
Run Code Online (Sandbox Code Playgroud)

注意:记住一件事,不要做tempObj = obj,然后它将无法工作,因为tempObj它也冻结在那里.

这里小提琴:http://jsfiddle.net/mpSYu/

  • 我了解您的意思。复制值是一种“解决”冻结对象的方法,但最后它都是`obj!= tempObj`-它们的签名不再相同。 (3认同)
  • @vivek_nk不,这不一样.仅仅因为新变量具有相同的名称并不意味着它是相同的引用(指针地址).你覆盖了冻结的`obj`,但仅限于本地范围.ps我个人喜欢那些物品不能解冻. (2认同)

Abd*_*UMI 11

有线解决方案:)

 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;
 }
Run Code Online (Sandbox Code Playgroud)

最佳实践:


 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}
Run Code Online (Sandbox Code Playgroud)
 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]
Run Code Online (Sandbox Code Playgroud)

  • 这并没有解冻,这复制了对象,完全不同的东西 (30认同)
  • 这应该是公认的答案。尽管另一个答案在技术上是正确的,但这完成了OP的任务。 (2认同)
  • 为了记录,这个问题的所有答案都是错误的,并涉及一个超出仍然冻结对象的新副本...... (2认同)

Ven*_*ryx 10

您无法解冻冻结的对象。

但是,您可以通过将 Object.freeze 方法覆盖为无操作来使讨厌的库在将来无法冻结任何内容:

Object.freeze = function(obj) { return obj; }; // just return the original object
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,这就足够了。只需在加载库之前运行上面的代码,它就不能再冻结任何东西了。; )


编辑:某些库(例如immer@7.0.7)有问题,除非在调用后Object.isFrozen(obj)返回。trueObject.freeze(obj)

因此,下面是一种更安全的阻止对象冻结的方法:(原语检查是因为WeakSet如果您传入原语会出错)

const fakeFrozenObjects = new WeakSet();
function isPrimitive(val) {
    return val == null || (typeof val != "object" && typeof val != "function");
}
Object.freeze = obj=>{
    if (!isPrimitive(obj)) fakeFrozenObjects.add(obj);
    return obj;
};
Object.isFrozen = obj=>{
    if (isPrimitive(obj)) return true;
    return fakeFrozenObjects.has(obj);
};
Run Code Online (Sandbox Code Playgroud)

  • @amay0048 垫片*添加*行为。这*删除*现有行为。这是一个糟糕的想法,绝对不应该在生产中使用。`Object.freeze` 的工作方式是有原因的。 (14认同)
  • 使用垫片来消除生产中的行为是一个糟糕的主意。另一方面,如果你想破解,你可以做任何你想做的事情来实现你的目标。 (3认同)
  • 这对我来说似乎很合理,就像反向垫片一样。为什么这被否决了? (2认同)
  • 您可以通过检查要解冻的对象的标志来扩展函数覆盖,这样它就永远不会被冻结。其他物体仍然可以冻结。 (2认同)

joe*_*dle 5

您无法解冻(解冻)一个对象,但如果该对象只是基元的集合(没有函数或类),您可以像这样获得该对象的解冻克隆:

const unfrozenObj = JSON.parse(JSON.stringify(frozenObj));
Run Code Online (Sandbox Code Playgroud)

  • 我想知道你是否可以将其视为解冻。您本质上是在创建一个新对象,冻结的对象仍然是不可变的 (3认同)