Czy istnieje operator" null coalescing " w JavaScript?

Czy istnieje operator koalescencyjny null w Javascript?

Na przykład w C# mogę to zrobić:

String someString = null;
var whatIWant = someString ?? "Cookies!";

Najlepsze przybliżenie, jakie mogę znaleźć dla Javascript, to użycie operatora warunkowego:

var someString = null;
var whatIWant = someString ? someString : 'Cookies!';

Co jest w pewnym sensie ohydne IMHO. Stać mnie na więcej?

Author: user2864740, 2009-01-24

8 answers

Odpowiednikiem JavaScript operatora C# null (??) jest użycie logicznego lub (||):

var whatIWant = someString || "Cookies!";

Istnieją przypadki (wyjaśnione poniżej), że zachowanie nie będzie pasować do C#, ale jest to ogólny, zwięzły sposób przypisywania wartości domyślnych / alternatywnych w JavaScript.


Wyjaśnienie

Niezależnie od typu pierwszego operandu, jeśli oddanie go do wartości logicznej spowoduje false, przypisanie użyje drugiego operandu. Uważaj na wszystkie przypadki poniżej:

alert(Boolean(null)); // false
alert(Boolean(undefined)); // false
alert(Boolean(0)); // false
alert(Boolean("")); // false
alert(Boolean("false")); // true -- gotcha! :)

Oznacza to:

var whatIWant = null || new ShinyObject(); // is a new shiny object
var whatIWant = undefined || "well defined"; // is "well defined"
var whatIWant = 0 || 42; // is 42
var whatIWant = "" || "a million bucks"; // is "a million bucks"
var whatIWant = "false" || "no way"; // is "false"
 1627
Author: Ates Goral,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-24 19:10:23
function coalesce() {
    var len = arguments.length;
    for (var i=0; i<len; i++) {
        if (arguments[i] !== null && arguments[i] !== undefined) {
            return arguments[i];
        }
    }
    return null;
}

var xyz = {};
xyz.val = coalesce(null, undefined, xyz.val, 5);

// xyz.val now contains 5

To rozwiązanie działa jak funkcja SQL coalesce, przyjmuje dowolną liczbę argumentów i zwraca null, jeśli żaden z nich nie ma wartości. Zachowuje się jak C#?? operator w tym sensie, że"", false I 0 są uważane za nie NULL i dlatego liczą się jako wartości rzeczywiste. Jeśli pochodzisz z środowiska. NET, będzie to najbardziej naturalne rozwiązanie.

 59
Author: Brent Larsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-19 18:42:35

Jeśli || jako zamiennik C# ' S ?? nie jest wystarczająco dobry w Twoim przypadku, ponieważ pochłania puste ciągi i zera, zawsze możesz napisać własną funkcję:

 function $N(value, ifnull) {
    if (value === null || value === undefined)
      return ifnull;
    return value;
 }

 var whatIWant = $N(someString, 'Cookies!');
 38
Author: sth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-09 16:42:53

Nikt tu nie wspomniał o potencjale NaN, który-dla mnie-jest również wartością zerową. Więc pomyślałem, że dodam moje 2 centy.

Dla podanego kodu:

var a,
    b = null,
    c = parseInt('Not a number'),
    d = 0,
    e = '',
    f = 1
;

Jeśli użyjesz operatora ||, otrzymasz pierwszą wartość nie-false:

var result = a || b || c || d || e || f; // result === 1

Jeśli użyjesz typowej metody coalesce, jak napisano tutaj, otrzymasz c, która ma wartość: NaN

var result = coalesce(a,b,c,d,e,f); // result.toString() === 'NaN'

Żadne z nich nie wydaje mi się właściwe. In my own little world of logika koalescencji, która może różnić się od Twojego świata, uważam undefined, null i NaN za wszystkie "null-owskie". Spodziewałbym się więc powrotu d (zero) z metody coalesce.

Jeśli czyjś mózg działa jak mój, a Ty chcesz wykluczyć NaN, to ta metoda osiągnie to:

function coalesce() {
    var i, undefined, arg;

    for( i=0; i < arguments.length; i++ ) {
        arg = arguments[i];
        if( arg !== null && arg !== undefined
            && (typeof arg !== 'number' || arg.toString() !== 'NaN') ) {
            return arg;
        }
    }
    return null;
}

Dla tych, którzy chcą, aby Kod był jak najkrótszy, i nie przeszkadza ci mały brak jasności, możesz również użyć tego, jak zasugerował @impinball. Wykorzystuje to fakt, że NaN nigdy nie jest równa NaN. Możesz przeczytać więcej na ten temat tutaj: dlaczego NaN nie jest równe NaN?

function coalesce() {
    var i, arg;

    for( i=0; i < arguments.length; i++ ) {
        arg = arguments[i];
        if( arg != null && arg === arg ) { //arg === arg is false for NaN
            return arg;
        }
    }
    return null;
}
 10
Author: Kevin Nelson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:54

Tak, już wkrótce. Zobacz wniosek tutaj i status realizacji tutaj .

Wygląda tak:

x ?? y

Przykład

const response = {
  settings: {
    nullValue: null,
    height: 400,
    animationDuration: 0,
    headerText: '',
    showSplashScreen: false
  }
};

const undefinedValue = response.settings?.undefinedValue ?? 'some other default'; // result: 'some other default'
const nullValue = response.settings?.nullValue ?? 'some other default'; // result: 'some other default'
const headerText = response.settings?.headerText ?? 'Hello, world!'; // result: ''
const animationDuration = response.settings?.animationDuration ?? 300; // result: 0
const showSplashScreen = response.settings?.showSplashScreen ?? true; // result: false
 9
Author: vaughan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-07 09:32:28

Obecnie brak wsparcia, ale pracuje nad nim proces standaryzacji JS: https://github.com/tc39/proposal-optional-chaining

 6
Author: Elmar Jansen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-16 21:17:38

Uważaj na specyficzną dla JavaScript definicję null. istnieją dwie definicje "brak wartości" w javascript. 1. Null: gdy zmienna jest null, to znaczy, że nie zawiera żadnych danych, ale zmienna jest już zdefiniowana w kodzie. tak:

var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts

W takim przypadku typem zmiennej jest rzeczywiście Object. sprawdź to.

window.alert(typeof myEmptyValue); // prints Object
  1. Undefined: gdy zmienna nie została wcześniej zdefiniowana w kodzie i zgodnie z oczekiwaniami nie zawiera żadnej wartości. jak to:

    if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); }
    // alerts
    

W takim przypadku typ zmiennej jest 'undefined'.

Zauważ, że jeśli używasz operatora porównania konwertującego Typ (==), JavaScript będzie działał jednakowo dla obu tych pustych wartości. aby je rozróżnić, Zawsze używaj operatora porównania typu-ścisłego (===).

 4
Author: farzad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-08 14:53:16

Po przeczytaniu twojego wyjaśnienia, odpowiedź @ Ates Goral podaje, jak wykonać tę samą operację, którą wykonujesz w C# w JavaScript.

@ Gumbo ' s answer provides the best way to checking for null; jednakże, ważne jest, aby zauważyć różnicę w == versus === w JavaScript szczególnie jeśli chodzi o kwestie sprawdzania dla undefined i/lub null.

Jest naprawdę dobry artykuł o różnicy w dwóch kategoriach tutaj. Zasadniczo zrozum, że jeśli użyj == zamiast ===, JavaScript spróbuje połączyć wartości, które porównujesz i zwróci wynik porównania po tej koalescencji.

 3
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-24 18:29:21