未定義の場合、JavaScriptは変数を設定します


172

javascript変数をテストし、未定義の場合はそれを定義できることはわかっていますが、なんらかの方法はありません。

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

はるかに明確な方法のように思われ、私はこれを他の言語で見たことがあると確信しています。


30
それは「未定義」のテストではなく、「偽り」のテストです
Alnitak

3
localStorage.getItem()ユーザーが(少なくとも、Chromeで)無効にクッキーを持っている場合は、内部でそれをラップすることもできますので、例外がスローされますtry...catch
urish

回答:


304

はい、それは可能ですが、厳密に言うと、真に未定義でなく、取得した値がfalseの場合にデフォルト値が割り当てられます。したがって、一致していないだけでなく、、、、 (しかしありません)。undefinednullfalse0NaN"" "0"

変数が厳密undefinedな場合にのみデフォルトに設定したい場合、最も安全な方法は次のように書くことです:

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

新しいブラウザでは、実際に書くのは安全です:

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

ただしundefined、値が定義されているという名前の変数を宣言することが許可されていた古いブラウザでは、これを覆すことができるため、テストが失敗することに注意してください。


3
このパターンが他のJSライブラリに含まれていないことに驚いています。
joemaller 2013

var x = (x === undefined ? def_val : x);少し長くして使用することの欠点がありvar x = (typeof x === 'undefined') ? def_val : x;ます。動作は異なりますか?
マルコパシュコフ2014

3
古いブラウザでは@marco undefinedが再定義される可能性があり、同等性テストが失敗していました。
アルニタク2014

@Alnitak OPが使用しているものと同様の構文を使用し、未定義をチェックするための最良のアプローチは何ですか?
Ivo Pereira 2014

@IvoPereira ||未定義の厳密なテストではこのアプローチを使用できませんundefined。条件付きの明示的なテストを使用する必要があります。
Alnitak

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/en-US/docs/Web/JavaScript/Reference/…)ここでは関係ありません。
Trevor Dixon

5
同意しません。それらの両方を理解し、適切なものを使用してください。特に、Object.is両方のオペランドがである可能性がある場合に使用しますNaN
Trevor Dixon、

2
Object.is()が100%のユースケースで機能し、===が98%のユースケースで機能する場合、なぜ===を使用するリスクがあるのですか?例:console.log(+0 === -0); // trueを出力しますが、console.log(Object.is(+0、-0)); // falseを出力します-どちらが良いですか?負の0は正の0と同じですか?それはあなた自身に尋ねなければならない質問ですが、Object.is()を使用する場合、あなたは常に答えを知っています。それらは同じではないため、falseの出力は正しい期待される結果です。
スターリングボーン

2
ここでの特定のコンテキストは常にと比較されundefinedます。したがって===、98%だけでなく、100%の時間で動作します。===特に一目で読みやすく、不必要なメソッド呼び出しを回避できるという利点があります。個人的に私はObject.is()状況がそれを必要とするときだけ使用し、===他のすべての場合に好むでしょう。
blubberdiblub

1
絶対に; あなたが経験豊富なコーダーなら。誤って等号を忘れていない限り、その場合==がどこかで機能しない理由のデバッグは、開発者に望まないことです。申し訳ありませんが常にObject.is()を使用するより安全です。仕様に含まれているのは、開発者がバグの少ないコードを作成できるようにするためです。
スターリングボーン

7

いくつかの場所で「未定義の場合は変数を設定する」必要がありました。@Alnitakの回答を使用して関数を作成しました。うまくいけば、それは誰かを助けます。

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

使用法:

hasPoints = setDefaultVal(this.hasPoints, true);

6

typeof代わりにチェックする方が理にかなっていundefinedますか?0未定義のときに変数をに設定すると、数値が期待されると思います。

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

この場合、getVariableが数値(文字列、オブジェクトなど)ではない場合、setVariableは次のように設定されます。0


5

ES2020回答

Nullish合体場合オペレータは、デフォルト値を設定することができますvaluenullまたは未定義です。

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

ただし、演算子を合体nullishのようなfalsy値、他のタイプのデフォルト値は返さないことに注意してください0とを''

オペレーターのブラウザーサポートは制限されていることに注意してください。caniuseのデータによると、ブラウザの48.34%のみがサポートされています(2020年4月現在)。Node.jsのサポートはバージョン14で追加されました


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を使用している場合(私はのように)それは、かなり便利だと簡潔
ダミアン・グリーン

1

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


localStorage.getItem('value'))リターンの場合も0を割り当てないfalse
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の値を上書きする場合は、最後の2つのパラメーターをオプションとして呼び出します。次の例は、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で演算子を「合体nullは」ありますか?)?重複しているか、コメント内の関連する質問にリンクしているので、VTCの方がいいのではないですか?
user4642212

質問はすべて少し異なります。そのように答えもそうです。例は、一目でインラインコンテキストを改善するために一貫しています。おそらくより詳細にリンクすることができたかもしれませんが、人々がソリューションをスキップする可能性がある追加のホップが必要になるでしょう
Gibolt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.