Object.freeze
或Object.seal
的反面是什么?是否有一个具有诸如detach等名称的函数?
答案 0 :(得分:73)
没有办法做到这一点,一旦物体被冻结,就无法解冻它。
冻结物体是锁定的最终形式。曾经是一个对象 已被冻结,它不能解冻 - 也不能被篡改 方式。这是确保您的对象保持不变的最佳方法 就像你离开他们一样,无限期地
答案 1 :(得分:14)
我认为你可以做一些技巧:
此处的代码:
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/
答案 2 :(得分:7)
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]
答案 3 :(得分:2)
您无法解冻冻结的物体。
但是,你可以通过将Object.freeze方法重写为无操作来使得讨厌的库不能在将来冻结任何东西:
Object.freeze = function(obj) { return obj; }; // just return the original object
在大多数情况下,这已经足够了。只需在加载库之前运行上面的代码,它就不能再冻结任何东西了。 ; )
答案 4 :(得分:1)
在FF 52中测试:
至于冻结对象(符号)' parent' -object(其中它被符号引用,旁边/除了代码的其他部分中的其他符号引用)对象)不是冷冻(就像窗口一样),但是可以通过删除操作符删除它,如:
删除window.tinymce;
即使window.tinymce已经被Object.freeze(window.tinymce)冻结了; (否则'父母将成为某种"冻结"本身,因为包含不可破坏的对象引用,这将使未冻结的父对象的符号不可删除...)
就删除/删除之前已经创建的原始对象的复制/克隆/重建/自己的版本/已经删除/没有原始限制(冻结,可扩展性,可配置性,可写性等等) on),可以将该副本/克隆/重建/自己的版本/的引用/分配给原始的符号位置, - 就像这样:
window.tinymce = the_copy_clone_reconstruction_own_version_object;
确保拥有" copy_clone_reconstruction_own_version_object"在您的变通方法代码完成后未被删除的全局范围! [实际上,对象本身应该被删除/它的内存被释放/只是当它的最后一个引用被从任何范围中移除时 - 一段时间之后,由于垃圾收集,但我'我不确定优先级高于'功能完成 - 删除所有本地变量']
未经测试: 其他符号引用可以指向原始的,冻结的/受限制的对象,例如,设置为
的东西myobj.subobj = window.tinymce;
在你的行动开始之前。
这样的东西(myobj.subobj)可能会(尝试一下!)进一步指向冷冻原件(?)。
下一个概念: 未经测试!
如何使用' proxy' -feature来包装value-get / -set和其他行为(函数,......)的冻结/密封或其他限制(可扩展性,...... )对象?
创建于GLOBAL范围之类的
p =新代理(目标,处理程序);
要么
window.p =新代理(目标,处理程序);
//其中target是用于拦截/挂钩/监视的对象,例如" window.tinymce"
代理主题的mdn-doc说,包装对象的限制(冻结,...)被认为是,但是可以引用core- / original-object本身(由代理包装)并且最终可能不会引用代理人制作的模仿......
范围规则可能适用于上述......
答案 5 :(得分:1)
你无法解冻(解冻)一个对象,但如果该对象只是一个基元的集合(没有函数或类),你就可以得到一个解冻的对象克隆:
fun isNotificationAllowed(context: Context): Boolean {
return if (isOOrLater()) {
areNotificationsEnabled(context) and isChannelDisabled(context)
} else {
areNotificationsEnabled(context)
}
}
private fun areNotificationsEnabled(context: Context) =
NotificationManagerCompat.from(context).areNotificationsEnabled()
@RequiresApi(api = Build.VERSION_CODES.O)
private fun isChannelDisabled(context: Context): Boolean{
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID)
return channel.importance != NotificationManager.IMPORTANCE_NONE
}
private fun isOOrLater() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
答案 6 :(得分:0)
您可以使用spread运算符解冻数组。
//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
答案 7 :(得分:0)
我也是问题。为了解决这个问题,我使用了JavaScript JSON API来解冻我的对象:<plugin name="cordova-plugin-battery-status" source="npm" spec="~1.1.1" />
<plugin name="cordova-plugin-camera" source="npm" spec="~2.1.1" />
<plugin name="cordova-plugin-media-capture" source="npm" spec="~1.2.0" />
<plugin name="cordova-plugin-console" source="npm" spec="~1.0.2" />
<plugin name="cordova-plugin-contacts" source="npm" spec="~2.0.1" />
<plugin name="cordova-plugin-device" source="npm" spec="~1.1.1" />
<plugin name="cordova-plugin-device-motion" source="npm" spec="~1.2.0" />
<plugin name="cordova-plugin-device-orientation" source="npm" spec="~1.0.2" />
<plugin name="cordova-plugin-dialogs" source="npm" spec="~1.2.0" />
<plugin name="cordova-plugin-file" source="npm" spec="~4.1.1" />
<plugin name="cordova-plugin-file-transfer" source="npm" spec="~1.5.0" />
<plugin name="cordova-plugin-geolocation" source="npm" spec="~2.1.0" />
<plugin name="cordova-plugin-globalization" source="npm" spec="~1.0.3" />
<plugin name="cordova-plugin-inappbrowser" source="npm" spec="~1.3.0" />
<plugin name="cordova-plugin-media" source="npm" spec="~2.2.0" />
<plugin name="cordova-plugin-network-information" source="npm" spec="~1.2.0" />
<plugin name="cordova-plugin-splashscreen" source="npm" spec="~3.2.1" />
<plugin name="cordova-plugin-statusbar" source="npm" spec="~2.1.2" />
<plugin name="cordova-plugin-vibration" source="npm" spec="~2.1.0" />
<plugin name="cordova-plugin-whitelist" source="npm" spec="~1.2.1" />
<plugin name="cordova-plugin-x-socialsharing" source="npm" />
。之后,我做了我需要的所有突变。
答案 8 :(得分:0)
聚会晚了一点,但是您也可以在可变变量(let
)中创建对象,并在需要重置时将原始对象重新分配给该变量。
例如:
let obj = { objProp: "example" };
if (condition) {
Object.freeze(obj);
}
else {
obj = { objProp: "example" };
}
答案 9 :(得分:0)
根据答案和评论,似乎人们在需要对冻结对象进行变异时找到了这篇文章。说“那是不可能的”虽然准确,但并不是很有帮助。
考虑到这一点,这是我根据 2014 年@Abdennour TOUMI 的回答提出的现代变体
function unfreeze(obj) {
if (Object.isFrozen(obj)) {
return Object.assign({}, obj);
}
return obj;
}
这是一个如何使用它的例子:
let myObj = { one: "1", two: "2", three: "3" };
Object.freeze(myObj);
// error
// myObj.one = "4";
// succeeds
myObj = unfreeze(myObj);
myObj.one = "4";
答案 10 :(得分:-2)
我尝试了这个,它工作正常
let obj = {name:'Trickester', age:25}
Object.freeze(obj)
let newObj = obj
obj = null
obj = newObj
//make whatever changes you