677 Stimmen

JavaScript isset() entspricht

In PHP können Sie Folgendes tun if(isset($array['foo'])) { ... } . In JavaScript verwenden Sie oft if(array.foo) { ... } dasselbe zu tun, aber das ist nicht genau die gleiche Aussage. Die Bedingung wird auch als falsch ausgewertet, wenn array.foo existiert zwar, ist aber false ou 0 (und wahrscheinlich auch andere Werte).

Was ist die perfekte Entsprechung von PHPs isset in JavaScript?

Im weiteren Sinne wäre ein allgemeiner, vollständiger Leitfaden zum Umgang von JavaScript mit Variablen, die nicht existieren, Variablen ohne Wert usw. sinnvoll.


Update : Vor 11 Jahren und 11 Monaten habe ich diese Frage gestellt, und wow, sie ist immer noch sehr aktuell. Ich bin mir ziemlich sicher, dass ich, als ich diese Frage schrieb, nur wissen wollte, wie man das Vorhandensein einer Eigenschaft in einem assoziativen Array (auch bekannt als Wörterbuch) prüft, und daher beinhalten die (für mich) richtigen Antworten hasOwnProperty oder die in Betreiber. Ich war nicht daran interessiert, lokale oder globale Variablen zu überprüfen.

Aber obwohl ich mich gut daran erinnere, geht diese Absicht aus der Frage, so wie sie geschrieben ist, nicht klar hervor oder steht sogar in direktem Widerspruch zu ihr! Ich habe das assoziative Array nie erwähnt, und PHPs isset tut auch diese anderen Dinge. Dies soll uns allen eine Lehre sein, wie wichtig es ist, die Anforderungen in einer Frage richtig zu formulieren, und auch, dass globale Variablen, lokale Variablen, Objekteigenschaften, Wörterbuchschlüssel und was auch immer nicht Huey, Dewey und Louie sind.

In der Zwischenzeit (heh), viele viele Menschen haben Antworten zu diesem Effekt als auch, so dass für diejenigen von Ihnen, die diese Frage durch Google gefunden, gut, ich bin froh, meine vage in gewisser Weise geholfen, ich denke. Wie auch immer, ich wollte das nur klarstellen.

1124voto

Christian C. Salvadó Punkte 763569

Ich verwende im Allgemeinen die typeof Betreiber:

if (typeof obj.foo !== 'undefined') {
  // your code here
}

Es wird zurückgegeben "undefined" entweder wenn die Eigenschaft nicht existiert oder ihr Wert undefined .

(Siehe auch: <a href="https://stackoverflow.com/questions/3420071/difference-between-undefined-and-not-being-defined-in-javascript/3420160#3420160">Der Unterschied zwischen <code>undefined</code> und nicht definiert werden. </a>)

Es gibt andere Möglichkeiten, um herauszufinden, ob eine Eigenschaft auf einem Objekt existiert, wie die hasOwnProperty Methode:

if (obj.hasOwnProperty('foo')) {
  // your code here
}

Und die in Betreiber:

if ('foo' in obj) {
  // your code here
}

Der Unterschied zwischen den beiden letztgenannten ist, dass die hasOwnProperty Methode prüft, ob die Eigenschaft existiert physisch auf das Objekt (die Eigenschaft wird nicht vererbt).

El in Operator prüft alle Eigenschaften, die in der Prototypenkette nach oben erreichbar sind, z. B.:

var obj = { foo: 'bar'};

obj.hasOwnProperty('foo'); // true
obj.hasOwnProperty('toString'); // false
'toString' in obj; // true

Wie Sie sehen können, hasOwnProperty gibt zurück. false und die in Operator kehrt zurück true bei der Überprüfung der toString Methode wird diese Methode in der Prototypenkette nach oben definiert, da obj erbt Form Object.prototype .

83voto

Enom Punkte 828

Ein altes Thema, aber es gibt neue Wege, ein Äquivalent zu betreiben isset() .

ESNext (Stufe 4 Dezember 2019)

Zwei neue Syntaxen ermöglichen es uns, die Verwendung von isset() Funktionalität:

Bitte lesen Sie die Dokumente und achten Sie auf die Browserkompatibilität.

Antwort

Siehe unten für eine Erklärung. Hinweis: Ich verwende die StandardJS-Syntax

Beispiel für die Verwendung

// IMPORTANT pass a function to our isset() that returns the value we're
// trying to test(ES6 arrow function)
isset(() => some) // false

// Defining objects
let some = { nested: { value: 'hello' } }

// More tests that never throw an error
isset(() => some) // true
isset(() => some.nested) // true
isset(() => some.nested.value) // true
isset(() => some.nested.deeper.value) // false

// Less compact but still viable except when trying to use `this` context
isset(function () { return some.nested.deeper.value }) // false

Antwort Funktion

/**
 * Checks to see if a value is set.
 *
 * @param   {Function} accessor Function that returns our value
 * @returns {Boolean}           Value is not undefined or null
 */
function isset (accessor) {
  try {
    // Note we're seeing if the returned value of our function is not
    // undefined or null
    return accessor() !== undefined && accessor() !== null
  } catch (e) {
    // And we're able to catch the Error it would normally throw for
    // referencing a property of undefined
    return false
  }
}

NPM-Paket

Diese Antwortfunktion ist verfügbar als isset-php Paket auf NPM. Das Paket enthält einige Verbesserungen wie Typüberprüfung und Unterstützung mehrerer Argumente.

npm install --save isset-php

Die vollständige Dokumentation finden Sie in der README .

const isset = require('isset-php')
let val = ''

// This will evaluate to true so the text will be printed.
if (isset(() => val)) {
  console.log('This val is set so I will print.')
}

Erläuterung

PHP

Beachten Sie, dass Sie in PHP auf jede Variable in jeder Tiefe verweisen können - selbst der Versuch, auf ein auf ein Nicht-Array als Array zuzugreifen, gibt eine einfache true ou false :

// Referencing an undeclared variable
isset($some); // false

$some = 'hello';

// Declared but has no depth(not an array)
isset($some); // true
isset($some['nested']); // false

$some = ['nested' => 'hello'];

// Declared as an array but not with the depth we're testing for
isset($some['nested']); // true
isset($some['nested']['deeper']); // false

JavaScript

In JavaScript haben wir diese Freiheit nicht; wir werden immer einen Fehler erhalten, wenn wir dasselbe tun dasselbe tun, weil die Engine sofort versucht, auf den Wert von deeper bevor wir es in unser isset() Funktion so...

// Common pitfall answer(ES6 arrow function)
const isset = (ref) => typeof ref !== 'undefined'

// Same as above
function isset (ref) { return typeof ref !== 'undefined' }

// Referencing an undeclared variable will throw an error, so no luck here
isset(some) // Error: some is not defined

// Defining a simple object with no properties - so we aren't defining
// the property `nested`
let some = {}

// Simple checking if we have a declared variable
isset(some) // true

// Now trying to see if we have a top level property, still valid
isset(some.nested) // false

// But here is where things fall apart: trying to access a deep property
// of a complex object; it will throw an error
isset(some.nested.deeper) // Error: Cannot read property 'deeper' of undefined
//         ^^^^^^ undefined

Mehr fehlende Alternativen:

// Any way we attempt to access the `deeper` property of `nested` will
// throw an error
some.nested.deeper.hasOwnProperty('value') // Error
//   ^^^^^^ undefined

// Similar to the above but safe from objects overriding `hasOwnProperty`
Object.prototype.hasOwnProperty.call(some.nested.deeper, 'value') // Error
//                                        ^^^^^^ undefined

// Same goes for typeof
typeof some.nested.deeper !== 'undefined' // Error
//          ^^^^^^ undefined

Und einige funktionierende Alternativen, die schnell überflüssig werden können:

// Wrap everything in try...catch
try {
  if (isset(some.nested.deeper)) {
    // ...
  }
} catch (e) {}

try {
  if (some.nested.deeper !== undefined && some.nested.deeper !== null) {
    // ...
  }
} catch (e) {}

// Or by chaining all of the isset which can get long
isset(some) && isset(some.nested) && isset(some.nested.deeper) // false
//                        ^^^^^^ returns false so the next isset() is never run

Schlussfolgerung

Alle anderen Antworten - obwohl die meisten machbar sind...

  1. Gehen Sie davon aus, dass Sie nur prüfen wollen, ob die Variable nicht undefiniert ist. für einige Anwendungsfälle in Ordnung ist, aber trotzdem einen Fehler auslösen kann
  2. Nehmen Sie an, dass Sie nur versuchen, auf eine Eigenschaft der obersten Ebene zuzugreifen, was wiederum für einige für einige Anwendungsfälle in Ordnung
  3. Sie dazu zwingen, einen weniger idealen Ansatz als den von PHP zu verwenden isset()
    z.B.. isset(some, 'nested.deeper.value')
  4. 使用方法 eval() was funktioniert, aber ich persönlich vermeide

Ich denke, ich habe eine Menge davon abgedeckt. Es gibt einige Punkte in meiner Antwort, die ich nicht anspreche, weil sie - obwohl relevant - nicht Teil der Frage sind Frage sind (z.B.. Kurzschluss ). Falls erforderlich, kann ich meine Antwort jedoch mit Links zu einigen der technischen Aspekten auf Anfrage aktualisieren.

Ich habe viel zu viel Zeit damit verbracht, also hoffe ich, dass es den Leuten weiterhilft.

Vielen Dank fürs Lesen!

26voto

Ijas Ameenudeen Punkte 8699

Verweis auf SOURCE

    module.exports = function isset () {
  //  discuss at: http://locutus.io/php/isset/
  // original by: Kevin van Zonneveld (http://kvz.io)
  // improved by: FremyCompany
  // improved by: Onno Marsman (https://twitter.com/onnomarsman)
  // improved by: Rafa Kukawski (http://blog.kukawski.pl)
  //   example 1: isset( undefined, true)
  //   returns 1: false
  //   example 2: isset( 'Kevin van Zonneveld' )
  //   returns 2: true

  var a = arguments
  var l = a.length
  var i = 0
  var undef

  if (l === 0) {
    throw new Error('Empty isset')
  }

  while (i !== l) {
    if (a[i] === undef || a[i] === null) {
      return false
    }
    i++
  }

  return true
}

phpjs.org ist größtenteils zugunsten von locutus aufgegeben worden Hier ist der neue Link http://locutus.io/php/var/isset

23voto

kennytm Punkte 488916
if (!('foo' in obj)) {
  // not set.
}

9voto

Diese einfache Lösung funktioniert zwar, aber nicht bei der Prüfung tiefer Objekte.

function isset(str) {
    return window[str] !== undefined;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X