Tie*_*eme 16 javascript hashmap immutability ecmascript-6
我正在寻找一种方法来冻结原生ES6地图.
Object.freeze并且Object.seal似乎不起作用:
let myMap = new Map([["key1", "value1"]]);
// Map { 'key1' => 'value1' }
Object.freeze(myMap);
Object.seal(myMap);
myMap.set("key2", "value2");
// Map { 'key1' => 'value1', 'key2' => 'value2' }
Run Code Online (Sandbox Code Playgroud)
这是预期的行为,因为冻结属性objects和maps没有objects或可能这是一个错误/尚未实现?
是的,我知道,我应该使用Immutable.js,但有没有办法用本机ES6地图做到这一点?
没有,你可以写一个包装来做到这一点.Object.freeze锁定对象的属性,但Map实例是对象时,它们存储的值不是属性,因此冻结对它们没有影响,就像任何其他隐藏了内部状态的类一样.
在真正的ES6环境中,支持扩展内置(不是Babel),你可以这样做:
class FreezableMap extends Map {
set(...args){
if (Object.isFrozen(this)) return this;
return super.set(...args);
}
delete(...args){
if (Object.isFrozen(this)) return false;
return super.delete(...args);
}
clear(){
if (Object.isFrozen(this)) return;
return super.clear();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您需要在ES5环境中工作,您可以轻松地为一个包装类Map而不是扩展Map该类.
@loganfsmyth,你的回答给了我一个想法,这是怎么回事:
function freezeMap(myMap){
if(myMap instanceof Map) {
myMap.set = function(key){
throw('Can\'t add property ' + key + ', map is not extensible');
};
myMap.delete = function(key){
throw('Can\'t delete property ' + key + ', map is frozen');
};
myMap.clear = function(){
throw('Can\'t clear map, map is frozen');
};
}
Object.freeze(myMap);
}
Run Code Online (Sandbox Code Playgroud)
这对我来说很完美:)
在评论中更新了@Bergi中的点数:
var mapSet = function(key){
throw('Can\'t add property ' + key + ', map is not extensible');
};
var mapDelete = function(key){
throw('Can\'t delete property ' + key + ', map is frozen');
};
var mapClear = function(){
throw('Can\'t clear map, map is frozen');
};
function freezeMap(myMap){
myMap.set = mapSet;
myMap.delete = mapDelete;
myMap.clear = mapClear;
Object.freeze(myMap);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2073 次 |
| 最近记录: |