Entspricht JavaScript isset ()


553

In PHP können Sie tun if(isset($array['foo'])) { ... }. In JavaScript verwenden Sie häufig if(array.foo) { ... }dasselbe, aber dies ist nicht genau dieselbe Aussage. Die Bedingung wird auch als falsch ausgewertet, wenn array.foosie existiert, aber ist falseoder 0(und wahrscheinlich auch andere Werte).

Was ist das perfekte Äquivalent zu PHPs issetin JavaScript?

Im weiteren Sinne wäre eine allgemeine, vollständige Anleitung zum Umgang mit nicht vorhandenen Variablen, Variablen ohne Wert usw. in JavaScript praktisch.


1
Ich habe eine Funktion geschrieben, die die Existenz einer Objekteigenschaft unabhängig von der Tiefe der Abfrage testet : stackoverflow.com/a/12681101/1268003 Mit meinem Code und einigen Kenntnissen, die @CMS in diesem Thread teilt, können Sie problemlos eine globale Eigenschaft schreiben Funktion, die sehr ähnlich wie PHP: s isset funktioniert.
Martin Andersson

3
Wenn Sie Underscore.js verwenden, versuchen Sie_.isUndefined(arr.foo)
Vitalii Fedorenko

Optionale Verkettung ist wahrscheinlich das, wonach die meisten Leute suchen werden. Stackoverflow.com/a/60845999/2100372
zoran404

Antworten:


938

Ich benutze im Allgemeinen den typeofOperator:

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

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

(Siehe auch: Unterschied zwischen undefinedund nicht definiert. )

Es gibt andere Möglichkeiten, um herauszufinden, ob eine Eigenschaft für ein Objekt vorhanden ist, z. B. die hasOwnPropertyMethode:

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

Und der inBetreiber:

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

Der Unterschied zwischen den letzten beiden besteht darin, dass die hasOwnPropertyMethode prüft, ob die Eigenschaft physisch auf dem Objekt vorhanden ist (die Eigenschaft wird nicht vererbt).

Der inBediener überprüft alle in der Prototypenkette erreichbaren Eigenschaften, z.

var obj = { foo: 'bar'};

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

Wie Sie sehen können, hasOwnPropertygibt diese Methode bei der Überprüfung der Methode zurück falseund der inOperator wird in der Prototypenkette definiert, da sie die Form erbt .truetoStringobjObject.prototype


23
Warum typeofeher verwenden als if( obj.foo !== undefined )?
Matt Ball

7
Ah. Eines Tages werde ich ein Stück wirklich browserübergreifendes Javascript schreiben. Bis dahin ...
Matt Ball

37
Das Problem dabei ist, dass Sie eine Fehlermeldung erhalten, wenn Sie versuchen, tiefere Eigenschaften zu überprüfen, zum Beispiel: obj.thisdoesntexist.foo! == undefined. In PHP können Sie isset oder leer und sicher in jeder Tiefe verwenden.
Enrique

6
IE8 hat nicht "hasOwnPropery"
max4ever

12
Genau, PHP erlaubt im isset($abc->def->ghi->jkl)Gegensatz zum JavaScript- typeofOperator , ohne eine Ausnahme auszulösen und das Skript anzuhalten . Sie müssen so etwas wie try{ abc.def.ghi.jkl; isset=true } catch(e){ isset=false }
Steven Pribilinskiy

43

Uralter Thread, aber es gibt neue Möglichkeiten, ein Äquivalent auszuführen isset().

ESNext (Phase 4 Dezember 2019)

Zwei neue Syntax ermöglichen es uns, die Verwendung von isset()Funktionen erheblich zu vereinfachen :

Bitte lesen Sie die Dokumente und beachten Sie die Browserkompatibilität.

Vorherige Antwort

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

Beispiel 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

Antwortfunktion

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

Erläuterung

PHP

Beachten Sie, dass Sie in PHP auf jede Variable in jeder Tiefe verweisen können. Selbst wenn Sie versuchen, auf ein Nicht-Array als Array zuzugreifen, wird ein einfaches trueoder Folgendes zurückgegeben 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

JS

In JavaScript haben wir diese Freiheit nicht. Wenn wir dasselbe tun, wird immer eine Fehlermeldung angezeigt, da JS sofort versucht, auf den Wert von zuzugreifen, deeper bevor wir ihn in unsere isset()Funktion einbinden können.

// 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

Weitere fehlgeschlagene Alternativen:

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

Object.hasOwnProperty('value', some.nested.deeper) // 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 { isset(some.nested.deeper) } catch (e) {}
try { typeof some.nested.deeper !== 'undefined' } 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

Fazit

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

  1. Angenommen, Sie überprüfen nur, ob die Variable nicht undefiniert ist, was für einige Anwendungsfälle in Ordnung ist, aber dennoch einen Fehler auslösen kann
  2. Angenommen, Sie versuchen nur, auf eine Eigenschaft der obersten Ebene zuzugreifen, was für einige Anwendungsfälle wiederum in Ordnung ist
  3. Erzwingen Sie einen weniger idealen Ansatz in Bezug auf PHPs, isset()
    zisset(some, 'nested.deeper.value')
  4. Verwenden Sie, eval()was funktioniert, aber ich persönlich vermeide

Ich glaube, ich habe viel davon behandelt. In meiner Antwort mache ich einige Punkte, die ich nicht anspreche, weil sie - obwohl relevant - nicht Teil der Frage sind. Bei Bedarf kann ich meine Antwort jedoch mit Links zu einigen der technischeren Aspekte aktualisieren, je nach Bedarf.

Ich habe viel Zeit damit verbracht, hoffentlich hilft es den Leuten dabei.

Danke fürs Lesen!


25

Verweis auf QUELLE

    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 im Ruhestand. Hier ist der neue Link http://locutus.io/php/var/isset


6
Dies löst beim Aufruf eine Ausnahme aus, isset(abc.def.ghi)falls abc.defundefiniert ist. Wenn Sie diese Lösung jedoch mit der kombinieren, die einen Variablennamen in Form einer Zeichenfolge akzeptiert, ist sie mit der PHP-Version identisch.
Steven Pribilinskiy


8
//
//  tring to reference non-existing variable throws ReferenceError 
//  before test function is even executed
//
//  example, if you do:
//    
//     if ( isset( someVar ) ) 
//        doStuff( someVar );
//   
//  you get a ReferenceError ( if there is no someVar... ) 
//  and isset fn doesn't get executed.
//
//  if you pass variable name as string, ex. isset( 'novar' );, 
//  this might work:
//
function isset ( strVariableName ) { 

    try { 
        eval( strVariableName );
    } catch( err ) { 
        if ( err instanceof ReferenceError ) 
           return false;
    }

    return true;

 } 
//
//

8

Diese einfache Lösung funktioniert, jedoch nicht für die Tiefenobjektprüfung.

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

6

Ich verwende diese generische Funktion immer, um Fehler bei primitiven Variablen sowie bei Arrays und Objekten zu vermeiden.

isset = function(obj) {
  var i, max_i;
  if(obj === undefined) return false;
  for (i = 1, max_i = arguments.length; i < max_i; i++) {
    if (obj[arguments[i]] === undefined) {
        return false;
    }
    obj = obj[arguments[i]];
  }
  return true;
};

console.log(isset(obj));                   // returns false
var obj = 'huhu';
console.log(isset(obj));                   // returns true
obj = {hallo:{hoi:'hoi'}};
console.log(isset(obj, 'niet'));           // returns false
console.log(isset(obj, 'hallo'));          // returns true
console.log(isset(obj, 'hallo', 'hallo')); // returns false
console.log(isset(obj, 'hallo', 'hoi'));   // returns true


4

Dies ist eine ziemlich kugelsichere Lösung zum Testen, ob eine Variable vorhanden ist:

var setOrNot = typeof variable !== typeof undefined ? true : false;

Leider können Sie es nicht einfach in eine Funktion einkapseln.

Sie könnten daran denken, so etwas zu tun:

function isset(variable) {
    return typeof variable !== typeof undefined ? true : false;
}

Dies führt jedoch zu einem Referenzfehler, wenn variablekeine Variable definiert wurde, da Sie eine nicht vorhandene Variable nicht an eine Funktion weitergeben können:

Nicht gefangener Referenzfehler: foo ist nicht definiert

Auf der anderen Seite können Sie testen, ob Funktionsparameter undefiniert sind:

var a = '5';

var test = function(x, y) {
    console.log(isset(x));
    console.log(isset(y));
};

test(a);

// OUTPUT :
// ------------
// TRUE
// FALSE

Obwohl kein Wert für yan function weitergegeben wird, funktioniert testunsere issetFunktion in diesem Zusammenhang einwandfrei, da ysie in function testals undefinedWert bekannt ist.


Minor nit: `? true: false` ist überflüssig. Das Ergebnis von !==ist bereits ein Boolescher Wert.
ToolmakerSteve

4
(typeof SOMETHING) !== 'undefined'

Es ist zu lang, um es zu schreiben, wenn es verwendet wird. Wir können das typeofSchlüsselwort jedoch nicht in eine Funktion packen, da vor dem Aufruf der Funktion ein Fehler wie folgt ausgelöst wird:

function isdef($var) {
    return (typeof $var) !== 'undefined';
}

isdef(SOMETHING); ///// thrown error: SOMETHING is not defined

Also habe ich einen Weg gefunden:

function isdef($type) {
    return $type !== 'undefined';
}

isdef(typeof SOMETHING);

Es kann sowohl mit einzelnen Variablen (Variablen, die überhaupt nicht vorhanden sind) als auch mit Objekteigenschaften (nicht vorhandene Eigenschaften) arbeiten. Und nur 7 mehr Zeichen als PHP isset.


Dies funktioniert bei mir und wird verwendet, um zu überprüfen, ob eine bestimmte JSON-Antwort vorhanden ist.
Julius

3

Diese Lösung hat bei mir funktioniert.

function isset(object){
    return (typeof object !=='undefined');
}

5
Aufruf isset(var)mit varnicht gesetzt:ReferenceError: var is not defined
Gui Imamura

3
function isset(variable) {
    try {
        return typeof eval(variable) !== 'undefined';
    } catch (err) {
        return false;
    }
}

4
füge auch eine Beschreibung hinzu.
Shree Krishna

Wie bereits in mehreren früheren Antworten erwähnt, wird ein ReferenceError ausgelöst, wenn eine Variable aufgerufen wird, die noch nie deklariert wurde. ZB isset(someVar)wo someVarwurde nie deklariert. Wenn Sie dies jedoch tun eval, beabsichtigen Sie wahrscheinlich, eine Zeichenfolge zu übergeben. Verwendung anzeigen. Ist Ihre beabsichtigte Verwendung isset('someVar')? Wenn ja, sieht dies ähnlich aus wie diese frühere Antwort - was ist mit Ihrer Antwort neu?
ToolmakerSteve


3

Um zu überprüfen, ob ein HTML-Block vorhanden ist oder nicht, verwende ich diesen Code:

if (typeof($('selector').html()) != 'undefined') {
    // $('selector') is existing
    // your code here
}

2

Geben Sie den Objektpfad als Zeichenfolge an. Anschließend können Sie diese Zeichenfolge in einen Pfad aufteilen und auflösen hasOwnProperty bei jedem Schritt während Sie das Objekt selbst bei jeder Iteration überschreiben.

Wenn Sie in einer ES6-Umgebung codieren, sehen Sie sich diese Stackoverflow-Fragen an .

var a;

a = {
    b: {
        c: 'e'
    }
};

function isset (obj, path) {
    var stone;

    path = path || '';

    if (path.indexOf('[') !== -1) {
        throw new Error('Unsupported object path notation.');
    }

    
    path = path.split('.');
    
    do {
        if (obj === undefined) {
            return false;
        }

        stone = path.shift();
        
        if (!obj.hasOwnProperty(stone)) {
            return false;
        }
        
        obj = obj[stone];
        
    } while (path.length);

    return true;
}

console.log(
    isset(a, 'b') == true,
    isset(a, 'b.c') == true,
    isset(a, 'b.c.d') == false,
    isset(a, 'b.c.d.e') == false,
    isset(a, 'b.c.d.e.f') == false
);


2

Ich benutze eine Funktion, die Variablen und Objekte überprüfen kann. Sehr praktisch für die Arbeit mit jQuery

    function _isset (variable) {
        if(typeof(variable) == "undefined" || variable == null)
            return false;
        else
            if(typeof(variable) == "object" && !variable.length) 
                return false;
            else
                return true;
    };

Wie bereits in mehreren früheren Antworten erwähnt, wird ein ReferenceError ausgelöst, wenn eine Variable aufgerufen wird, die noch nie deklariert wurde.
ToolmakerSteve

1

Es war wirklich ein Problem für mich, als ich auf eine tiefere Eigenschaft eines Objekts zugegriffen habe, also habe ich eine Funktion erstellt, die den Eigenschaftswert zurückgibt, falls vorhanden, andernfalls wird false zurückgegeben. Sie können es verwenden, um Ihre Zeit zu sparen,

//Object on which we want to test
var foo = {
    bar: {
        bik: {
            baz: 'Hello world'
        }
    }
};


/*
USE: To get value from the object using it properties supplied (Deeper),
    if found it will return the property value if not found then will return false

You can use this function in two ways
WAY - 1:
Passing an object as parameter 1 and array of the properties as parameter 2
EG: getValueFromObject(foo, ['bar', 'bik', 'baz']);
WAY - 2: (This will work only if, your object available in window object)
Passing an STRING as parameter 1(Just similarly how we retrieve value form object using it's properties - difference is only the quote)
EG: getValueFromObject('foo.bar.bik.baz');
*/
function getValueFromObject(object, properties) {
    if(typeof(object) == 'string') {            //Here we extract our object and it's properties from the string
        properties = object.split('.');
        object = window[properties[0]];
        if(typeof(object) == 'undefined') {
            return false;
        }
        properties.shift();
    }
    var property = properties[0];
    properties.shift();
    if(object != null && typeof(object[property]) != 'undefined') {
        if(typeof(object[property]) == 'object') {
            if(properties.length != 0) {
                return getValueFromObject(object[property], properties);    //Recursive call to the function
            } else {
                return object[property];
            }
        } else {
            return object[property];
        }
    } else {
        return false;
    }
}
console.log(getValueFromObject('fooo.bar.bik.baz'));        //false
console.log(getValueFromObject('foo.bar.bik.baz'));         //Hello world
console.log(getValueFromObject('foo'));                     //false
console.log(getValueFromObject('foo.bar.bik'));             //returns an object { baz: 'Hello World' }
console.log(getValueFromObject(foo, ['bar', 'bik']));       //returns an object { baz: 'Hello World' }
console.log(getValueFromObject(foo, ['bar', 'bik', 'baz']));//Hello world

1

Wenn Sie überprüfen möchten, ob ein Element vorhanden ist, verwenden Sie einfach den folgenden Code:

if (object) {
  //if isset, return true
} else {
  //else return false
}

Dies ist ein Beispiel:

function switchDiv() {
    if (document.querySelector("#divId")) {
        document.querySelector("#divId").remove();
    } else {
        var newDiv = document.createElement("div");
        newDiv.id = "divId";
        document.querySelector("body").appendChild(newDiv);
    }
}

document.querySelector("#btn").addEventListener("click", switchDiv);
#divId {
    background: red;
    height: 100px;
    width: 100px;
    position: relative;
    
}
<body>
  <button id="btn">Let's Diiiv!</button>
</body>


0
if (var) {
  // This is the most concise equivalent of Php's isset().
} 

0

PHP-Handbuch sagen:

isset - Bestimmen Sie, ob eine Variable gesetzt und nicht NULL ist

Und Schnittstelle so etwas:

bool isset ( mixed $var [, mixed $... ] )

Der Parameter $varist die zu prüfende Variable. Es kann jedoch eine beliebige Anzahl von Parametern haben.

isset () gibt zurück, TRUEwenn var existiert und einen anderen Wert als hat NULL.FALSEAndernfalls.

Ein Beispiel:

$foo = 'bar';
var_dump(isset($foo));        -> true

$baz = null;
var_dump(isset($baz));        -> false

var_dump(isset($undefined));  -> false

Aus diesem Grund ist es anscheinend nicht möglich, ein genaues Äquivalent der PHP- isset()Funktion zu schreiben . Zum Beispiel, wenn wir so anrufen:

if (isset(some_var)) {

}

function issset() {
    // function definition
}

Javascript-Trigger Uncaught ReferenceError: some_var is not defined at (file_name):line_number. Das Wichtige und Bemerkenswerte an diesem Verhalten ist, dass beim Versuch, nicht vorhandene Variablen an normale Funktionen zu übergeben, ein Fehler ausgelöst wird.

Aber in PHP isset() gibt es eigentlich keine regulären Funktionen, sondern Sprachkonstrukte. Das heißt, sie sind Teil der PHP-Sprache selbst, halten sich nicht an die normalen Funktionsregeln und können daher davonkommen, keinen Fehler für nicht vorhandene Variablen auszulösen. Dies ist wichtig, wenn Sie herausfinden möchten, ob eine Variable vorhanden ist oder nicht. In Javscript wird jedoch in erster Linie ein Fehler ausgelöst, z. B. ein Funktionsaufruf mit nicht vorhandenen Variablen.

Mein Punkt ist, dass wir es nicht als äquivalente Javscript-Funktion schreiben können, aber wir können so etwas tun

if (typeof some_var !== 'undefined') {
   // your code here
}

Wenn Sie genau den gleichen Effekt PHP wollen, überprüfen Sie auch, ob varable nicht ist NULL

Zum Beispiel

$baz = null;
var_dump(isset($baz));        -> false

Also können wir dies in Javascript integrieren, dann sieht es so aus:

if (typeof some_var !== 'undefined' && some_var !== null) {
   // your code here
}

0

Javascript isset

let test = {
  a: {
    b: [0, 1]
  }
};

console.log(test.isset('a.b'))   // true
console.log(test.isset('a.b.1')) // true
console.log(test.isset('a.b.5')) // false
console.log(test.isset('a.c'))   // false
console.log('abv'.isset('0'))    // true

0

Seien Sie in ES6 vorsichtig , alle vorherigen Lösungen funktionieren nicht, wenn Sie eine Deklaration einer let-Variablen überprüfen und deklarieren möchten, wenn dies nicht der Fall ist

Beispiel

let myTest = 'text';

if(typeof myTest === "undefined") {
    var myTest = 'new text'; // can't be a let because let declare in a scope
}

Sie werden einen Fehler sehen

Nicht erfasster SyntaxError: Der Bezeichner 'myTest' wurde bereits deklariert

Die Lösung bestand darin, es durch eine Var zu ändern

var myTest = 'text'; // I replace let by a var

if(typeof myTest === "undefined") {
    var myTest = 'new text';
}

Eine andere Lösung, wenn Sie eine Let durch eine Var ändern können, müssen Sie Ihre Var entfernen

let myTest = 'text';

if(typeof myTest === "undefined") {
    myTest = 'new text'; // I remove the var declaration
}

-1
    isset('user.permissions.saveProject', args);

    function isset(string, context) {
        try {
            var arr = string.split('.');
            var checkObj = context || window;

            for (var i in arr) {
                if (checkObj[arr[i]] === undefined) return false;
                checkObj = checkObj[arr[i]];
            }

            return true;
        } catch (e) {
            return false;
        }
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.