javascript mengatur variabel jika tidak terdefinisi

172

Saya tahu bahwa saya dapat menguji variabel javascript dan kemudian mendefinisikannya jika tidak terdefinisi, tetapi apakah tidak ada cara untuk mengatakannya

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

sepertinya cara yang jauh lebih jelas, dan saya cukup yakin saya telah melihat ini dalam bahasa lain.

pedalpete
sumber
30
itu bukan ujian untuk "tidak terdefinisi", itu ujian untuk "falsey"
Alnitak
3
Perhatikan bahwa localStorage.getItem()akan mengeluarkan pengecualian jika pengguna telah menonaktifkan cookie (setidaknya di Chrome), jadi Anda mungkin ingin membungkusnya dalam try...catchklausa
urish
1
Kemungkinan duplikat dari Apa konstruk x = x || maksudmu?
Michał Perłakowski

Jawaban:

304

Ya, itu bisa melakukan itu, tetapi sebenarnya yang akan menetapkan nilai default jika nilai yang diambil adalah falsey , yang bertentangan dengan benar-benar tidak terdefinisi . Ini akan karena itu tidak hanya cocok undefinedtetapi juga null, false, 0, NaN, "" (tapi tidak "0" ).

Jika Anda ingin menetapkan ke default hanya jika variabel benar-benar undefinedmaka cara paling aman adalah menulis:

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

Pada browser yang lebih baru sebenarnya aman untuk menulis:

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

tetapi perlu diketahui bahwa ini mungkin untuk menumbangkan ini di browser lama di mana ia diizinkan untuk mendeklarasikan variabel bernama undefinedyang memiliki nilai yang ditentukan, yang menyebabkan tes gagal.

Alnitak
sumber
3
Saya terkejut pola ini tidak termasuk dalam lebih banyak JS libs.
joemaller
apakah ada kerugian menggunakan var x = (x === undefined ? def_val : x);sedikit lebih lama var x = (typeof x === 'undefined') ? def_val : x;. Apakah perilakunya berbeda?
Marco Pashkov
3
@marco di peramban yang lebih lama memungkinkan untuk undefineddidefinisikan ulang, menyebabkan pengujian kesetaraan gagal.
Alnitak
@Alnitak apa pendekatan terbaik untuk menggunakan sintaksis yang mirip dengan yang digunakan OP dan masih memeriksa tidak terdefinisi?
Ivo Pereira
@IvoPereira Anda tidak dapat menggunakan ||pendekatan dalam pengujian ketat untuk undefined, Anda harus menggunakan tes eksplisit untuk undefineddengan bersyarat.
Alnitak
26

Jawaban 2018 ES6 adalah :

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

Jika variabel x tidak terdefinisi, kembalikan variabel ... jika tidak, jika variabel x didefinisikan, kembalikan variabel x.

Sterling Bourne
sumber
4
Sejauh yang saya tahu, Object.istidak ada yang lebih baik daripada ===dalam kasus ini. "Operator === (dan operator == juga) memperlakukan nilai angka -0 dan +0 sama dan memperlakukan Number.NaN tidak sama dengan NaN." ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) Tidak masalah di sini.
Trevor Dixon
5
Saya tidak setuju. Kenali keduanya dan gunakan yang sesuai. Secara khusus, gunakan Object.isjika kedua operan mungkin NaN.
Trevor Dixon
2
Jika Object.is () bekerja pada 100% kasus penggunaan, dan === bekerja pada 98% kasus penggunaan, mengapa Anda berisiko menggunakan === sama sekali? Misalnya: console.log (+0 === -0); // menghasilkan true, sementara console.log (Object.is (+0, -0)); // keluaran salah - mana yang lebih baik? Apakah negatif 0 sama dengan positif 0? Itu pertanyaan yang harus Anda tanyakan pada diri sendiri, tetapi jika Anda menggunakan Object.is (), Anda selalu tahu jawabannya. Mereka tidak sama, jadi hasil false adalah hasil yang benar dan diharapkan.
Sterling Bourne
2
Konteks tertentu di sini selalu dibandingkan dengan undefined. Jadi ===akan bekerja 100% dari waktu, bukan hanya 98%. Keuntungan ===menjadi lebih mudah dibaca, terutama sekilas, lebih pendek dan menghindari pemanggilan metode yang tidak perlu. Secara pribadi saya hanya akan menggunakan Object.is()ketika situasi membutuhkannya dan lebih suka ===dalam semua kasus lainnya.
blubberdiblub
1
Benar; jika Anda seorang programmer yang berpengalaman. Kecuali jika Anda secara tidak sengaja lupa tanda sama dengan, dalam hal ini mengapa debug == tidak berfungsi di suatu tempat adalah sesuatu yang saya tidak akan pernah berharap pada pengembang mana pun. Lebih baik aman daripada menyesal dan selalu menggunakan Object.is (), Alasannya termasuk dalam spesifikasi khusus untuk membantu pengembang menulis kode kereta kurang.
Sterling Bourne
7

Saya perlu "mengatur variabel jika tidak terdefinisi" di beberapa tempat. Saya membuat fungsi menggunakan jawaban @Alnakak. Semoga ini membantu seseorang.

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

Pemakaian:

hasPoints = setDefaultVal(this.hasPoints, true);
Mcestone
sumber
6

Tampaknya lebih logis untuk memeriksa typeofbukan undefined? Saya berasumsi Anda mengharapkan nomor ketika Anda mengatur var 0ketika tidak ditentukan:

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

Dalam hal ini jika getVariablebukan angka (string, objek, apa pun), setVariable diatur ke0

Bruno
sumber
5

ES2020 Jawab

Dengan Operator Penggabungan Nullish , Anda dapat menetapkan nilai default jika valuenull atau tidak terdefinisi.

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

Namun, Anda harus menyadari bahwa operator penggabungan nol tidak mengembalikan nilai default untuk jenis nilai falsy lainnya seperti 0dan ''.

Perhatikan bahwa dukungan browser untuk operator terbatas. Menurut data dari caniuse , hanya 48,34% browser yang didukung (per April 2020). Dukungan Node.js telah ditambahkan di versi 14 .

gojun
sumber
2

Jika Anda seorang penggemar FP ( pemrograman fungsional ), Ramda memiliki fungsi pembantu yang rapi untuk ini yang disebut defaultTo :

pemakaian:

const result = defaultTo(30)(value)

Ini lebih berguna ketika berhadapan dengan undefinednilai boolean:

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

Damian Green
sumber
1
ini persis const result = value || 30;, kecuali menggunakan fungsi di antara dan +1000 byte lib
Adelin
1
@ Adelin tidak benar, ia juga menangani falsy untuk tipe boolean. Jika Anda sudah menggunakan Lib ini (seperti saya) maka itu cukup berguna, dan singkat
Damian Green
1

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

Zikes
sumber
Juga tidak akan menetapkan 0 jika localStorage.getItem('value'))kembalifalse
Karl Adler
1

Berlari ke skenario ini hari ini juga di mana saya tidak ingin nol ditimpa untuk beberapa nilai. Kami memiliki file dengan beberapa metode utilitas umum untuk skenario seperti ini. Inilah yang saya tambahkan untuk menangani skenario dan menjadi fleksibel.

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;
    }
}

Kemudian dapat dipanggil dengan dua parameter terakhir menjadi opsional jika saya hanya ingin menetapkan nilai yang tidak ditentukan atau juga menimpa nilai nol atau 0. Berikut adalah contoh panggilan untuk itu yang akan menetapkan ID ke -1 jika ID tidak terdefinisi atau nol, tetapi tidak akan menimpa nilai 0.

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

Di zaman kami, Anda sebenarnya dapat melakukan pendekatan dengan JS:

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

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

console.log(x); // default value

Jadi contoh Anda AKAN bekerja:

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

Bekerja bahkan jika nilai default adalah nilai boolean:

var setVariable = ( (b = 0) => b )( localStorage.getItem('value') );
Tsz Lam Yau
sumber
0

Menurut saya, untuk implementasi javascript saat ini,

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

adalah cara yang bagus untuk melakukan ini (menggunakan dekonstruksi objek).

TS
sumber
0

Penugasan nullish yang logis, solusi ES2020 +

Operator baru saat ini sedang ditambahkan ke browser, ??=, ||=, dan &&=. Pos ini akan menjadi fokus ??=.

Ini memeriksa apakah sisi kiri tidak terdefinisi atau nol, korsleting jika sudah ditentukan. Jika tidak, sisi kanan ditugaskan ke variabel sisi kiri.

Metode Membandingkan

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

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

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

Contoh dasar

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

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

// Equivalent to
a = a ?? true

Contoh Obyek / Array

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" }

?? = Dukungan Browser Juli 2020 - .03%

?? = Dokumentasi Mozilla

|| = Dokumentasi Mozilla

&& = Dokumentasi Mozilla

Gibolt
sumber
Apakah benar-benar ide yang bagus untuk menyalin jawaban ini ke dua pertanyaan lain ( Ganti nilai jika null atau tidak terdefinisi dalam JavaScript dan Apakah ada operator "null penggabungan" dalam JavaScript? )? Bukankah VTC lebih baik sebagai duplikat atau tautan ke pertanyaan terkait di komentar?
user4642212
Semua pertanyaannya sedikit berbeda; dengan demikian demikianlah jawabannya. Contohnya konsisten untuk meningkatkan konteks inline sekilas. Mungkin bisa ditautkan untuk lebih detail, tetapi akan membutuhkan hop ekstra yang dapat menyebabkan orang melewatkan solusi
Gibolt