Javascript equivalent of Python's dict.setdefault?
Javascript equivalent of Python's dict.setdefault?
在Python中,对于字典d
,
d.setdefault('key', value)
如果'key'
不在d
中,设置d['key'] = value
,否则保持不变。
在Javascript对象上是否有一种干净、习惯的方法来做到这一点,或者它是否需要if
语句?
if (!('key' in d)) d.key = value;
或
'key' in d || (d.key = value);
(最后一个使用条件表达式的短路行为)
在另一个答案中建议的" d.key || (d.key = value)
"是错误的:如果一个元素存在但求值为false
(false
, null
, 0
, -0
, ""
, undefined
, NaN
),它将被静默覆盖。
虽然这可能是有意的,但它很可能不是为上述所有的情况而设计的。因此,在这种情况下,分别检查值:
if (!('key' in d) || d.key === null) d.key = value;
现在你也可以做d.key ??= value
它基本上就像使用if
语句,但更短:
d.key || (d.key = value);
或
d.key = d.key || value;
更新:正如@bobtato所指出的,如果属性已经设置为false
的值,它将覆盖它,所以一个更好的方法是:
!d.key && d.key !== false && (d.key = value);
或者,按照他的建议去做(只是简写版):
'key' in d || (d.key = value);
// including overwriting null values:
('key' in d && d.key !== null) || (d.key = value);
没有内置的东西,但是这个函数可以做到:
function setDefault(obj, prop, deflt) {
return obj.hasOwnProperty(prop) ? obj[prop] : (obj[prop] = deflt);
}
如果obj
只包含非假值,obj[prop] || (obj[prop] = deflt)
是一个很好的简单替代(但deflt
将覆盖任何假值)。这还有一个额外的好处,即deflt
只在需要它的值时才会被计算,所以它是一个昂贵的表达式也是可以的。
不建议,也绝不是增加内置类的好主意。相反,最好创建自己的内置类实现,就像YUI库所做的那样(YArray等)。然而,我要反驳这一点,因为我经常发现实现像这样有用的快捷方式对于编写干净的可维护代码是有好处的:
if (undefined === Object.prototype.setdefault) {
Object.prototype.setdefault = function(key, def) {
if (! this.hasOwnProperty(key)) {
this[key] = def;
}
return this[key];
};
}
让我们看看它的实际效果…
var a = {};
a.setdefault('mylist', []).push(1);
a.setdefault('mylist', []).push(2);
console.log(a.mylist.toString());
1,2
正如已经指出的,使用thing = thing || defaultThing
从来都不是一个好主意,因为它只测试true
或thing == true
的非类型相等性。与类型相等相反:thing === true
或thing !== undefined
。因此,以内联方式正确编写setdefault
的唯一方法是在所有地方使用此代码片段:
/* null == thing is equivalent to... */
if (undefined !== thing && null !== thing) {
thing = defaultThing;
}
/* ...but it's not explicit and linters don't like it! */
但是,正如我已经说过的,这只会增加您的代码的膨胀,并且容易从"复制-粘贴"综合症中获得错误。
a={}
key='3'
value = 2
a[key] = a[key] == undefined ? value : a[key]
## a = {'3': 2 }
Typescript版本的@DS。的回答是:
export function setDefault<K extends string | number | symbol, T>(
obj: Record<K, T>,
prop: K,
deflt: T,
) {
// eslint-disable-next-line
return obj.hasOwnProperty(prop) ? obj[prop] : (obj[prop] = deflt);
}
// eslint-disable-next-line
行旨在忽略以下eslint错误:
9:3 error Return statement should not contain assignment no-return-assign
9:14 error Do not access Object.prototype method 'hasOwnProperty' from target object no-prototype-builtins
9:50 error Assignment to property of function parameter 'obj' no-param-reassign
如果有人知道如何改进解决方案,使这些错误被修复而不是被忽略,请告诉我。
老实说,如果不分配obj
参数,我不知道如何实现这一点。
- V8如何处理这个/dict
- 结构和dict之间的区别是什么
- 将带点的dict键展开为另一个dict
- 在Meteor中使用moment.tz.setDefault()时的作用域是什么
- 使用javascript中的另一个dict创建dict时出现意外的令牌
- Javascript iterate over python dict
- 用车把.js做一个“if x in dict(json)”语句
- HTML DOM.无论如何都要获取属性dict
- Meteor:访问子模板中的反应dict变量
- 将JavaScript对象/数组转换为Python dict/list的最快方法
- 将原型化方法放入js dict中
- Javascript equivalent of Python's dict.setdefault?
- 在dict内循环遍历json数组
- 通过dict数据类型创建TAB特定变量
- 在MongoDB mapReduce emit中包含dict作为值
- 特殊字符显示在Python Dict构建的表单AWS中,并通过django视图传递给js
- Javascript-将dict转换为数组