tanımsızsa javascript bir değişken ayarlar


172

Bir javascript değişkeni için test ve tanımsız ise tanımlayabilirsiniz biliyorum, ama söylemenin bir yolu yok

var setVariable = localStorage.getItem ('değer') || 0;

çok daha net bir yol gibi görünüyor ve eminim bunu diğer dillerde gördüm.


30
olduğunu değil "tanımsız" için bir test, bu "Falsey" için bir test
Alnitak

3
localStorage.getItem()Kullanıcı çerezleri devre dışı bıraktığında (en azından Chrome'da) bir istisna oluşturacağına dikkat edin, bu yüzden bir try...catchcümle içine sarmak isteyebilirsiniz
8'de

Yanıtlar:


304

Evet, bunu yapabilir, ancak kesin olarak söylemek gerekirse, geri alınan değer gerçekte tanımsız yerine falsey ise varsayılan değeri atayacaktır . Bu nedenle sadece maç olmaz , aynı zamanda , , , , (ama değil ).undefinednullfalse0NaN"" "0"

Yalnızca değişken kesinlikle ise varsayılan olarak ayarlamak istiyorsanız undefined, en güvenli yol yazmaktır:

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

Daha yeni tarayıcılarda yazmak gerçekten güvenlidir:

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

ancak bunu, undefinedtanımlı değere sahip adlı bir değişkenin bildirilmesine izin verildiği ve testin başarısız olmasına neden olan eski tarayıcılarda değiştirmenin mümkün olduğunu unutmayın .


3
Bu kalıbın daha fazla JS kütüphanesinde yer almadığına şaşırdım.
joemaller

var x = (x === undefined ? def_val : x);biraz daha uzun kullanmanın bir dezavantajı var var x = (typeof x === 'undefined') ? def_val : x;. Davranış farklı mı?
Marco Pashkov

3
@marco eski tarayıcılarda undefinedyeniden tanımlanabildi ve eşitlik testinin başarısız olmasına neden oldu.
Alnitak

@Alnitak, OP'nin kullandığı ile benzer bir sözdizimi kullanmak ve tanımsız olup olmadığını kontrol etmek için en iyi yaklaşım nedir?
Ivo Pereira

@IvoPereira Tanımı ||kesin olmayan bir testte tanımsız olarak kullanamazsınız, undefinedkoşullu ile açık bir test kullanmanız gerekir .
Alnitak

26

2018 ES6 yanıtı :

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

X değişkeni tanımsızsa y değişkeni döndürün ... aksi takdirde x değişkeni tanımlanmışsa x değişkeni döndürün.


4
Anlayabildiğim kadarıyla , bu durumda olduğundan Object.isdaha iyi değil ===. "=== işleci (ve == işleci) -0 ve +0 sayı değerlerine eşit ve Number.NaN değerlerine NaN değerine eşit davranmaz." ( developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/… ) Burada önemli değil.
Trevor Dixon

5
Katılmıyorum. İkisini de tanıyın ve uygun olanı kullanın. Özellikle, Object.isher iki işlenen de olabilirse kullanın NaN.
Trevor Dixon

2
Object.is (), kullanım örneklerinin% 100'ünde çalışıyorsa ve ===, kullanım örneklerinin% 98'inde çalışıyorsa, neden === kullanmıyorsunuz? Örneğin: console.log (+0 === -0); // çıktı çıktıları doğru, console.log (Object.is (+0, -0)); // yanlış çıktılar - hangisi daha iyi? Negatif 0, pozitif 0 ile aynı mıdır? Kendinize sormanız gereken soru bu, ancak Object.is () kullanırsanız, cevabı her zaman bilirsiniz. Aynı değildirler, bu nedenle yanlış çıktı doğru ve beklenen sonuçtur.
Sterling Bourne

2
Buradaki belirli bağlam her zaman ile karşılaştırılmaktadır undefined. Yani ===sadece% 98 değil, zamanın% 100'ü çalışacaktır. ===Olmanın avantajı , özellikle bir bakışta okunması daha kolaydır ve gereksiz bir yöntem çağrısını önler. Şahsen ben sadece Object.is()durum gerektirdiğinde kullanırım ve ===diğer tüm durumlarda tercih ederim .
blubberdiblub

1
Kesinlikle; eğer deneyimli bir kodlayıcıysanız. Yanlışlıkla eşit bir işareti unutmadığınız sürece, bu durumda neden == bir yerde çalışmıyor hata ayıklama, herhangi bir geliştirici üzerinde asla istemeyeceğim bir şeydir. Üzgünüm daha iyi güvenli ve her zaman Object.is () kullanın, nedeni spec dahil edildi özellikle geliştiriciler daha az buggy kod yazma yardımcı oldu.
Sterling Bourne

7

Ben birkaç yerde "tanımsız ise bir değişken ayarlamak" gerekiyordu. @Alnitak yanıtını kullanarak bir işlev oluşturdum. Umarım birine yardımcı olur.

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

Kullanımı:

hasPoints = setDefaultVal(this.hasPoints, true);

6

Bu check daha mantıklı görünüyor typeofyerine undefined? Ben 0tanımsız zaman var olarak ayarlamak gibi bir sayı beklediğiniz varsayıyorum :

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

Bu durumda getVariable, bir sayı değilse (dize, nesne, ne olursa olsun), setVariable öğesi0


5

ES2020 Yanıt

İle Nullish Birleştirme eğer Operatörü, varsayılan bir değer ayarlayabilirsiniz valuenull veya tanımlanmamıştır.

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

Ancak, nullish birleştirme operatörünün 0ve gibi diğer falsy değeri türleri için varsayılan değeri döndürmediğini bilmeniz gerekir ''.

Operatör için tarayıcı desteğinin sınırlı olduğunu unutmayın. Caniuse verilerine göre , tarayıcıların yalnızca% 48,34'ü desteklenmektedir (Nisan 2020 itibariyle). Sürüm 14'te node.js desteği eklendi .


2

Bir FP ( fonksiyonel programlama ) hayranıysanız, Ramda'nın defaultTo adında düzgün bir yardımcı işlevi vardır :

kullanımı:

const result = defaultTo(30)(value)

undefinedBoole değerleri ile uğraşırken daha kullanışlıdır :

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


1
Bu tam olarak const result = value || 30;, aradaki işlev ile +1000 bayt lib kullanması dışında
Adelin

1
@Adelin doğru değil, aynı zamanda boole türleri için de falsili işler. Bu lib'i zaten (benim gibi) kullanıyorsanız, o zaman oldukça yararlı ve kısa
Damian Green

1

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


Ayrıca 0 asign olmaz eğer localStorage.getItem('value'))dönerfalse
Karl Adler

1

Bugün de bu senaryoya koştum, burada sıfırın üzerine birkaç değer yazılmasını istemedim. Bunun gibi senaryolar için bazı yaygın yardımcı program yöntemlerine sahip bir dosyamız var. İşte senaryoyu ele almak ve esnek olmak için eklediğim şey.

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

Daha sonra yalnızca tanımsız değerler için ayar yapmak veya ayrıca null veya 0 değerlerinin üzerine yazmak istiyorsanız son iki parametre isteğe bağlı olarak çağrılabilir. Kimliği tanımlanmamış veya boşsa, ancak 0 değerinin üzerine yazmayacaksa, kimliği -1 olarak ayarlayan bir çağrı örneği.

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

1

Günümüzde aslında JS ile yaklaşımınızı yapabilirsiniz:

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

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

console.log(x); // default value

Yani örneğin çalışacak:

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

0

Varsayılan değer bir boole değeri olsa bile çalışır:

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

0

Bana öyle geliyor ki, javascript uygulamaları için,

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

bunu yapmanın güzel bir yoludur (nesne yapısökümünü kullanarak).


0

Mantıksal nullish ataması, ES2020 + çözümü

Yeni operatörleri şu anda tarayıcılar, ilave ediliyor ??=, ||=ve &&=. Bu yazıya odaklanılacak ??=.

Bu, sol tarafın tanımsız veya boş olup olmadığını, önceden tanımlanmışsa kısa devre olup olmadığını kontrol eder. Değilse, sağ taraf sol taraf değişkenine atanır.

Karşılaştırma Yöntemleri

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

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

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

Temel Örnekler

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

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

// Equivalent to
a = a ?? true

Nesne / Dizi Örnekleri

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

?? = Tarayıcı Desteği Temmuz 2020 - .03%

?? = Mozilla Belgeleri

|| = Mozilla Belgeleri

&& = Mozilla Belgeleri


İki diğer sorulara bu cevabı kopyalamak için iyi bir fikir gerçekten var mı ( eğer boş bir değeri değiştirin veya JavaScript tanımsız ve JavaScript operatöre bir “birleştirici boş” var mıdır? )? Yorumlarda VTC'yi yinelenen veya ilgili sorulara bağlantı olarak daha iyi değil mi?
user4642212

Soruların hepsi biraz farklı; cevaplar da öyle. Örnekler, bir bakışta satır içi bağlamı iyileştirmek için tutarlıdır. Muhtemelen daha fazla ayrıntı için bağlantı kurabilirdi, ancak insanların çözümü atlamasına neden olabilecek ekstra bir sıçrama gerektirebilirdi
Gibolt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.