Das Übergeben von NULL als Parameter in ES6 verwendet nicht den Standardparameter, wenn einer bereitgestellt wird

Lesezeit: 7 Minuten

Benutzeravatar von alacy
alay

Gibt es einen bekannten Grund, warum ich vorbeikomme? null als Parameter in ES6 verwendet nicht den Standardparameter, wenn einer bereitgestellt wird?

function sayHello(name = "World") {
    console.log("Hello, " + name + "!");
}

sayHello("Jim");     // Hello, Jim!
sayHello(undefined); // Hello, World!
sayHello(null);      // Hello, null!

  • weil null ein gültiger Wert ist?

    – toskv

    22. September 2015 um 19:14 Uhr

  • nein, ist es nicht 🙂 Sie können hier den Unterschied zwischen undefined und null lesen stackoverflow.com/questions/5076944/…

    – toskv

    22. September 2015 um 19:17 Uhr

  • @toskv Wenn undefined war nicht ein Wert, dann könnte es nicht zugewiesen werden, aber es kann sein. Dies ist der einfachste Test, um festzustellen, ob etwas ein Wert ist. Und ganz einfach, diese Antwort ist im Kontext falsch: undefined wird als verwendet Standardwert in bestimmten Fällen; Dies ist nicht undefiniert machen ‘kein Wert’. In Betracht ziehen: a = new Array(1). Dann a[0] wird die ergeben undefined Wert, obwohl 0 in a ist falsch. Dass es, a[0] enthält ‘keinen Wert’, obwohl dies der Fall sein wird auswerten zum (Standard) undefined Wert.

    – Benutzer2864740

    22. September 2015 um 19:17 Uhr


  • @toskv Ich habe oben erklärt, warum das falsch ist. Apropos “wenn die Variable nicht definiert wurde” (im Fall von typeof x === 'undefined'wo x allein würde/könnte einen ReferenceError werfen) hat keinen Einfluss darauf, dass undefined ist ein Wert. Insbesondere „undefined“ in JavaScript tut dies nicht bedeutet streng genommen „nicht definiert/deklariert“.

    – Benutzer2864740

    22. September 2015 um 19:21 Uhr


  • Ich glaube, ich habe mich vorher schlecht ausgedrückt. Es ist nicht so, dass die Variable nicht definiert ist, in diesem Fall zeigt die Variable auf einen noch nicht definierten Wert. Während var x = null bedeutet, dass x den definierten Wert von null hat. Sie können sich undefined als nicht initialisiert vorstellen, während null ohne Wert initialisiert wird. Es ist verwirrend, ich weiß. @FelixKling

    – toskv

    23. September 2015 um 5:44 Uhr

Benutzeravatar von rsp
bzw

Das ist nicht so offensichtlich

Ich habe einige Kommentare gelesen, warum undefined ist ganz anders als null und deshalb erklärt es das aktuelle Verhalten von Standardparametern.

Man könnte argumentieren, dass explizit undefiniert übergeben wird sollte nicht Auslösen der Standardwertsubstitution, denn wenn ich eine Funktion habe:

const f = (x = 'default') => console.log(x);

Ich möchte es drucken "default" wenn ich es ausführe als:

f();

aber ich möchte es drucken "undefined" wenn ich es explizit ausführe als:

f(undefined);

denn warum sollte ich sonst verwenden f(undefined) an erster Stelle? Meine Absicht ist hier eindeutig, ein Argument zu liefern, anstatt es wegzulassen.

Beispiele dagegen

Betrachten Sie nun diese Funktion:

const g = (...a) => console.log(JSON.stringify(a));

Wenn ich es verwende als:

g();

Ich bekomme: []

Aber wenn ich es verwende als:

g(undefined);

Ich bekomme: [null]

was deutlich zeigt, dass:

  1. Vorbeigehen undefined ist nicht das gleiche als überhaupt kein Argument weiterzugeben
  2. manchmal null kann sein ein Standardwert statt undefined

TC39-Entscheidung

Einige Hintergrundinformationen zum aktuellen Verhalten der Standardparameter finden Sie in den Sitzungsnotizen von TC39 vom 24. Juli 2012:

Übrigens zeigt es das ausdrücklich vorbei undefined ursprünglich nicht den Standardwert im ersten Entwurf auslösen und es gab eine Diskussion darüber, ob es das tun sollte oder nicht. Wie Sie also sehen können, war das aktuelle Verhalten für die TC39-Mitglieder nicht so offensichtlich, wie es jetzt für Leute zu sein scheint, die hier kommentieren.

Andere Sprachen

Allerdings ist die Entscheidung, was die Defaultwertsubstitution auslösen soll und was nicht, letztlich völlig willkürlich. Sogar mit einem separaten undefined und null kann aber ziemlich seltsam sein, wenn man darüber nachdenkt. Einige Sprachen haben nur undefined (wie undef in Perl), manche haben nur null (wie Java) verwenden einige Sprachen Entsprechungen von false oder eine leere Liste oder ein Array dafür (wie Schema, wo Sie eine leere Liste haben können oder #f (falsch), aber es gibt kein Äquivalent von null das würde sich sowohl von einer leeren Liste als auch von einem falschen Wert unterscheiden) und einige Sprachen haben nicht einmal Äquivalente von null, false oder undefined (wie C, das statt Ganzzahlen verwendet true und false und einen NULL-Zeiger, der eigentlich ein normaler Zeiger ist, der auf die Adresse 0 zeigt – wodurch diese Adresse unzugänglich wird, selbst wenn sie von einem Code zugeordnet wird, der auf Null-Zeiger testet).

Was du tun kannst

Jetzt kann ich verstehen, dass Sie Standardwerte für ersetzen müssen null. Leider ist dies kein Standardverhalten, aber Sie können eine einfache Funktion erstellen, die Ihnen hilft:

const N = f => (...a) => f(...a.map(v => (v === null ? undefined : v)));

Jetzt jedes Mal, wenn Sie Standardeinstellungen ersetzen möchten null Werte können Sie es so verwenden. ZB wenn Sie diese Funktion aus einem der obigen Beispiele haben:

const f = (x = 'default') => console.log(x);

es wird gedruckt "default" zum f() und f(undefined) aber nicht für f(null). Aber wenn Sie die verwenden N oben definierte Funktion zum Definieren der f funktionieren so:

const f = N((x = 'default') => console.log(x));

jetzt f() und f(undefined) aber auch f(null) Drucke "default".

Wenn Sie ein etwas anderes Verhalten wünschen, z. B. das Ersetzen von Standardwerten für leere Zeichenfolgen – nützlich für Umgebungsvariablen, die manchmal auf leere Zeichenfolgen gesetzt werden können, anstatt nicht vorhanden zu sein, können Sie Folgendes verwenden:

const N = f => (...a) => f(...a.map(v => (v === '' ? undefined : v)));

Wenn Sie möchten, dass alle falschen Werte ersetzt werden, können Sie es wie folgt verwenden:

const N = f => (...a) => f(...a.map(v => (v || undefined)));

Wenn Sie möchten, dass leere Objekte ersetzt werden, können Sie Folgendes verwenden:

const N = f => (...a) => f(...a.map(v => (Object.keys(v).length ? v : undefined)));

usw…

Fazit

Der Punkt ist, dass es Ihr Code ist und Sie wissen, was die API Ihrer Funktionen sein sollte und wie die Standardwerte funktionieren sollten. Glücklicherweise ist JavaScript leistungsfähig genug, damit Sie das, was Sie brauchen, mit etwas höherer Funktionsmagie leicht erreichen können (auch wenn dies sozusagen nicht das Standardverhalten von Standardwerten ist).

  • tolle antwort! sehr ausführlich und gut erklärt.

    – alay

    21. April 2017 um 13:55 Uhr

  • Nun muss explizit undefined übergeben werden Auch Auslösen der Standardwertersetzung

    – Arun CM

    11. Juli 2020 um 17:06 Uhr

  • @rsp, Danke für deine Antwort, nach vier Jahren komme ich genau zum Grund meines Problems.

    – AmerllicA

    9. Oktober 2021 um 4:20 Uhr

Genauso werden Standardparameter in der Spezifikation definiert. Sehen MDN: (Hervorhebung von mir)

Standardfunktionsparameter ermöglichen es, formale Parameter mit Standardwerten zu initialisieren, wenn kein Wert oder undefiniert ist bestanden.

null ist weder kein Wertnoch undefinedsodass die Standardinitialisierung nicht ausgelöst wird.

  • Und der Grund warum undefined besonders behandelt wird, weil “leere” Parameter gesetzt sind undefined. Wenn undefined nicht gleichbedeutend mit “kein Wert”, wäre dies ärgerlicher zu implementieren: function foo(bar) { return functionWithDefaults(bar); }; foo();. Der Nachteil ist, dass es nicht möglich ist, explizit zu übergeben undefinedaber wer macht das schon 😛

    – Felix Klinge

    22. September 2015 um 23:44 Uhr

  • Weiß jemand, warum sie entschieden haben, dass dies der richtige Weg ist? Es scheint mir, dass null die Verwendung eines Standardwerts auslösen sollte.

    – ThinkingInBits

    8. August 2016 um 19:39 Uhr

  • Es ist möglich, explizit zu übergeben undefined durch explizites Passieren undefinedz.B doSomething(undefined)sehen codepen.io/morewry/pen/KaEVmN?editors=0010.

    – mehr schief

    15. Februar 2017 um 2:50 Uhr

Benutzeravatar von taxicala
Taxila

null ein Wert ist, der nicht den zu verwendenden Standardwert auslöst, werden die Standardwerte verwendet, wenn das Argument ist undefined.

Ramdajs-Versionscode

// import ramda

// infra code
const isEmptyOrNil = (value) => isEmpty(value) || isNil(value)
const nullChange = (defaultValue) => (value) => isEmptyOrNil(value)? defaultValue: value

// single null
const _somef = (value) => value
const somefWithDefault = (defaultValue) => pipe(nullChange(defaultValue), _somef)
const somef = somefWithDefault('myValue')

somef(null)

// many args
const _somef2 = (value, value2, value3) => value + value2 + value3
const nullChangeMyValue = nullChange('myValue')
const somef2 = useWith(_somef2, [nullChangeMyValue, nullChangeMyValue, nullChangeMyValue])

somef2(null, undefined, 1234)

// many args2 version2
const nullChangeWith = (defaultValue) => nullChange(defaultValue)
const arrayNullChangeWith = (defaultValue) => (array) => array.map(nullChangeWith(defaultValue))
const arg2Array = (...args) => args
const funcApplyDefaultValue = (defaultValue) => (func) => pipe(
  arg2Array, arrayNullChangeWith(defaultValue), apply(func)
)

const v2somef2 = funcApplyDefaultValue(8)(_somef2)

v2somef2(1,2,null)

gits: https://gist.github.com/otwm/3a6358e53ca794cc2e57ade4af91d3bb

1434500cookie-checkDas Übergeben von NULL als Parameter in ES6 verwendet nicht den Standardparameter, wenn einer bereitgestellt wird

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy