使用ES6 Proxy对象,当普通对象中不存在属性时,可以返回默认值。
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy
如何使用地图进行此操作?我尝试了以下代码,但总是返回默认值:
var map = new Map ([
[1, 'foo'], // default
[2, 'bar'],
[3, 'baz'],
]);
var mapProxy = new Proxy(map, {
get: function(target, id) {
return target.has(id) ? target.get(id) : target.get(1);
},
});
console.log( mapProxy[3] ); // foo
这是因为映射键是数字,但代理属性名称始终是字符串。您需要先将id
强制转换为数字。
工作示例(需要现代JS引擎):
var map = new Map ([
[1, 'foo'], // default
[2, 'bar'],
[3, 'baz'],
]);
var mapProxy = new Proxy(map, {
get: function(target, id) {
// Cast id to number:
id = +id;
return target.has(id) ? target.get(id) : target.get(1);
},
});
console.log( mapProxy[3] ); // baz
console.log( mapProxy[10] ); // foo
写这篇文章的一个好方法是:
const map = new Map ([
[1, 'foo'], // default
[2, 'bar'],
[3, 'baz'],
]);
const get = (id) => map.get(id) ?? map.get(3); // 3 as default
console.log(get(1)); // Returns 'foo' as expected
console.log(get(42)); // Defaults to 'baz'
在Scala中,映射是带有getOrElse
方法的单子。如果monad(容器)不包含值,则其get
方法会异常失败,但getOrElse允许用户编写无误的代码
Map.prototype.getOrElse = function(key, value) {
return this.has(key) ? this.get(key) : value
}
var map = new Map ([[1, 'foo'], [2, 'bar'], [3, 'baz']]);
[map.get(1), map.getOrElse(10, 11)]; // gives 11
另一个选项是扩展您的地图withDefaultValue
方法
//a copy of map will have a default value in its get method
Map.prototype.withDefaultValue = function(defaultValue) {
const result = new Map([...this.entries()]);
const getWas = result.get; result.get = (key) =>
result.has(key) ? getWas.call(this, key) : defaultValue;
return result
}
map.withDefaultValue(12).get(10) // gives 12
这就是Scala中的操作方式。或者,至少看起来是这样。