javascript设置变量(如果未定义)


172

我知道我可以测试一个javascript变量,然后在未定义的情况下对其进行定义,但是没有任何说法

var setVariable = localStorage.getItem('value')|| 0;

似乎是一种更清晰的方法,而且我敢肯定我已经用其他语言看到过这一点。


30
不是对“ undefined”的测试,而是对“ falsey”的测试
Alnitak

3
请注意,localStorage.getItem()如果用户禁用了cookie(至少在Chrome中是这样),则将引发异常,因此您可能希望将其包装在一个try...catch子句中
促成2014年

Answers:


304

是的,它可以做到这一点,但严格来说,如果检索到的值为false,它将分配默认值,而不是真正的undefined。它将因此不仅符合undefined而且nullfalse0NaN"" (但没有 "0")。

如果仅在变量严格时才希望设置为默认值,undefined那么最安全的方法是编写:

var x = (typeof x === 'undefined') ? your_default_value : x;

在较新的浏览器上,实际上可以安全地编写:

var x = (x === undefined) ? your_default_value : x;

但请注意,有可能在允许声明undefined具有定义值的名为变量的较旧浏览器中进行颠覆,从而导致测试失败。


3
我很惊讶这种模式没有包含在更多的JS库中。
joemaller

使用var x = (x === undefined ? def_val : x);更长的时间有什么缺点吗var x = (typeof x === 'undefined') ? def_val : x;?行为是否不同?
Marco Pashkov 2014年

3
在较旧的浏览器中,@ marco可能undefined需要重新定义,从而导致相等性测试失败。
Alnitak

@Alnitak是使用与OP正在使用的语法相似并且仍检查未定义语法的最佳方法是什么?
伊沃·佩雷拉

@IvoPereira您不能||在未定义的严格测试中使用该方法,而必须在undefined有条件的情况下使用显式测试。
Alnitak 2014年

26

2018年ES6的答案是

return Object.is(x, undefined) ? y : x;

如果未定义变量x,则返回变量y ...否则,如果定义变量x,则返回变量x。


4
据我所知,Object.is这没有比===这更好的了。“ ===运算符(以及==运算符)将数字值-0和+0视为相等,并将Number.NaN视为不等于NaN。” (developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/…)在这里无关紧要。
Trevor Dixon '18年

5
我不同意。两者都知道,并使用适当的一个。特别是Object.is如果两个操作数都可能为,则使用NaN
特雷弗·迪克森

2
如果Object.is()适用于100%的用例,而===适用于98%的用例,那么为什么还要冒用===的风险?例如:console.log(+0 === -0); //输出true,而console.log(Object.is(+0,-0)); //输出false-哪个更好?负0是否等于正0?这是您必须问自己的问题,但是如果使用Object.is(),则始终知道答案。它们是不相同的,因此输出false是正确的预期结果。
Sterling Bourne

2
这里的特定上下文总是与进行比较undefined。因此,===它将100%地工作,而不仅仅是98%。它的优点===是易于阅读,尤其是一目了然,更短并且避免了不必要的方法调用。就个人而言,我只会Object.is()在情况需要时使用,而===在其他所有情况下都更喜欢。
blubberdiblub19年

1
绝对; 如果您是一位经验丰富的编码员。除非您不小心忘记了等号,否则在这种情况下调试为什么==在某处不起作用是我对任何开发人员都不希望的。安全性胜过遗憾,并且始终使用Object.is(),该规范中包括的原因专门用于帮助开发人员编写更少的错误代码。
斯特恩·伯恩

7

我需要在多个地方“设置未定义的变量”。我使用@Alnitak答案创建了一个函数。希望它可以帮助某人。

function setDefaultVal(value, defaultValue){
   return (value === undefined) ? defaultValue : value;
}  

用法:

hasPoints = setDefaultVal(this.hasPoints, true);

6

似乎更合理地检查typeof而不是undefined?我假设您在将var设置为0undefined时期望有一个数字:

var getVariable = localStorage.getItem('value');
var setVariable = (typeof getVariable == 'number') ? getVariable : 0;

在这种情况下,如果getVariable不是数字(字符串,对象等),则setVariable设置为0


5

ES2020答案

使用Nullish合并运算符,可以将默认值设置value为null或未定义。

const setVariable = localStorage.getItem('value') ?? 0;

但是,您应该注意,空值合并运算符不会为其他类型的伪造值(例如0和)返回默认值''

请注意,浏览器对操作员的支持是有限的。根据caniuse的数据,截至2020年4月,仅支持48.34%的浏览器。在版本14添加了 Node.js支持。


2

如果您是FP(功能编程)迷,Ramda为此提供了一个简洁的帮助器函数,称为defaultTo

用法:

const result = defaultTo(30)(value)

在处理undefined布尔值时更有用:

const result2 = defaultTo(false)(dashboard.someValue)


1
正是这样const result = value || 30;,除了使用中间函数和+1000字节的lib
Adelin

1
@Adelin不是正确的,它也可以处理布尔类型的错误。如果您已经在使用这个lib(就像我一样),那么它就非常有用,而且简洁
Damian Green

1

var setVariable = (typeof localStorage.getItem('value') !== 'undefined' && localStorage.getItem('value')) || 0;


如果localStorage.getItem('value'))返回,也不会赋0false
Karl Adler

1

今天也遇到这种情况,我不想为多个值覆盖零。对于这样的场景,我们有一个带有一些常用实用程序方法的文件。这是我为处理场景而添加的内容,并保持灵活。

function getIfNotSet(value, newValue, overwriteNull, overwriteZero) {
    if (typeof (value) === 'undefined') {
        return newValue;
    } else if (value === null && overwriteNull === true) {
        return newValue;
    } else if (value === 0 && overwriteZero === true) {
        return newValue;
    } else {
        return value;
    }
}

然后,如果我只想为未定义的值设置还是覆盖null或0值,则可以使用最后两个参数作为可选参数来调用它。这是对其进行调用的示例,如果ID未定义或为null,则会将ID设置为-1,但不会覆盖0值。

data.ID = Util.getIfNotSet(data.ID, -1, true);

1

在当今的时代,您实际上可以使用JS进行处理:

// Your variable is null
// or '', 0, false, undefined
let x = null;

// Set default value
x = x || 'default value';

console.log(x); // default value

因此,您的示例将起作用:

const setVariable = localStorage.getItem('value') || 0;

0

即使默认值为布尔值也可以使用:

var setVariable = ( (b = 0) => b )( localStorage.getItem('value') );

0

在我看来,对于当前的javascript实现,

var [result='default']=[possiblyUndefinedValue]

是执行此操作的一种好方法(使用对象解构)。


0

逻辑无效分配,ES2020 +解决方案

新的运营商目前正在被添加到浏览器??=||=&&=。这篇文章将重点关注??=

这将检查左侧是否未定义或为null,如果已定义则短路。如果不是,则将右侧分配给左侧变量。

比较方法

// Using ??=
name ??= "Dave"

// Previously, ES2020
name = name ?? "Dave"

// Before that (not equivalent, but commonly used)
name = name || "Dave" // name ||= "Dave"

基本范例

let a          // undefined
let b = null
let c = false

a ??= true  // true
b ??= true  // true
c ??= true  // false

// Equivalent to
a = a ?? true

对象/数组示例

let x = ["foo"]
let y = { foo: "fizz" }

x[0] ??= "bar"  // "foo"
x[1] ??= "bar"  // "bar"

y.foo ??= "buzz"  // "fizz"
y.bar ??= "buzz"  // "buzz"

x  // Array [ "foo", "bar" ]
y  // Object { foo: "fizz", bar: "buzz" }

?? =浏览器支持 2020年7月-.03%

?? = Mozilla文档

|| = Mozilla文档

&& = Mozilla文档


难道真是一个好主意,复制这个回答另外两个问题(替换值如果为null或在JavaScript中未定义是否有一个“空合并”运营商在JavaScript中?)?将VTC复制或链接到评论中的相关问题会更好吗?
user4642212

这些问题都稍有不同。因此,答案也是如此。这些示例可以一目了然地改善内联上下文。可能可以链接以获得更多详细信息,但可能需要额外的跳转才能导致人们跳过解决方案
Gibolt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.