JavaScript isset () equivalente

553

En PHP puedes hacer if(isset($array['foo'])) { ... }. En JavaScript a menudo se usa if(array.foo) { ... }para hacer lo mismo, pero esta no es exactamente la misma declaración. La condición también se evaluará como falsa si array.fooexiste pero es falseo 0(y probablemente también otros valores).

¿Cuál es el equivalente perfecto de PHP isseten JavaScript?

En un sentido más amplio, sería conveniente una guía general y completa sobre el manejo de JavaScript de variables que no existen, variables sin un valor, etc.

Bart van Heukelom
fuente
1
Escribí una función que probará la existencia de una propiedad de objetos sin importar la profundidad de la consulta: stackoverflow.com/a/12681101/1268003 Usando mi código, combinado con algunos conocimientos compartidos por @CMS en este hilo, puede escribir fácilmente un global función que funciona de manera muy similar a PHP: s isset.
Martin Andersson el
3
Si usa Underscore.js intente_.isUndefined(arr.foo)
Vitalii Fedorenko
El encadenamiento opcional es probablemente lo que la mayoría de la gente buscará stackoverflow.com/a/60845999/2100372
zoran404

Respuestas:

938

Generalmente uso el typeofoperador:

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

Volverá "undefined"si la propiedad no existe o si su valor es undefined.

(Ver también: Diferencia entre undefinedy no se define ) .

Hay otras formas de averiguar si existe una propiedad en un objeto, como el hasOwnPropertymétodo:

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

Y el inoperador:

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

La diferencia entre los dos últimos es que el hasOwnPropertymétodo verificará si la propiedad existe físicamente en el objeto (la propiedad no se hereda).

El inoperador verificará todas las propiedades accesibles en la cadena del prototipo, por ejemplo:

var obj = { foo: 'bar'};

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

Como puede ver, hasOwnPropertyregresa falsey el inoperador regresa truecuando verifica el toStringmétodo, este método se define en la cadena del prototipo, porque objhereda la forma Object.prototype.

CMS
fuente
23
¿Por qué usar en typeoflugar de if( obj.foo !== undefined )?
Matt Ball
77
Ah Algún día escribiré una pieza de Javascript verdaderamente cruzado. Hasta entonces ...
Matt Ball
37
El problema con esto es que obtiene un error cuando intenta verificar propiedades más profundas, por ejemplo: obj.thisdoesntexist.foo! == undefined. En PHP puedes usar isset o empty y con seguridad en cualquier profundidad.
Enrique
66
IE8 no tiene "hasOwnPropery"
max4ever
12
Exactamente, PHP permite isset($abc->def->ghi->jkl)sin generar una excepción y detener el script, a diferencia del typeofoperador de JavaScript . Tienes que usar algo como try{ abc.def.ghi.jkl; isset=true } catch(e){ isset=false }
Steven Pribilinskiy
43

Tema antiguo, pero hay nuevas formas de ejecutar un equivalente isset().

ESNext (Etapa 4 de diciembre de 2019)

Dos nuevas sintaxis nos permiten simplificar enormemente el uso de la isset()funcionalidad:

Lea los documentos y tenga en cuenta la compatibilidad del navegador.

Respuesta anterior

Vea a continuación la explicación. Tenga en cuenta que uso la sintaxis StandardJS

Ejemplo de uso

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

Función de respuesta

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

Explicación

PHP

Tenga en cuenta que en PHP puede hacer referencia a cualquier variable a cualquier profundidad, incluso tratando de acceder a una matriz que no sea una matriz, ya que una matriz devolverá un simple trueo 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

En JavaScript, no tenemos esa libertad, siempre obtendremos un error si hacemos lo mismo porque JS está intentando acceder inmediatamente al valor de deeper antes de poder ajustarlo en nuestra isset()función, así que ...

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

Más alternativas fallidas:

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

Y algunas alternativas de trabajo que pueden volverse redundantes rápidamente:

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

Conclusión

Todas las otras respuestas, aunque la mayoría son viables ...

  1. Suponga que solo está verificando si la variable no está indefinida, lo cual está bien para algunos casos de uso, pero aún puede arrojar un Error
  2. Suponga que solo está intentando acceder a una propiedad de nivel superior, lo que de nuevo está bien para algunos casos de uso
  3. Obligarle a utilizar un enfoque menos que ideal en relación con PHP, isset()
    por ejemploisset(some, 'nested.deeper.value')
  4. Uso eval()que funciona pero yo personalmente evito

Creo que lo cubrí mucho. Hay algunos puntos que hago en mi respuesta que no menciono porque, aunque relevantes, no son parte de la pregunta. Sin embargo, si es necesario, puedo actualizar mi respuesta con enlaces a algunos de los aspectos más técnicos según la demanda.

Pasé mucho tiempo en esto, así que espero que ayude a la gente.

¡Gracias por leer!

Enom
fuente
25

Referencia a FUENTE

    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 está mayormente retirado a favor de locutus Aquí está el nuevo enlace http://locutus.io/php/var/isset

Ijas Ameenudeen
fuente
66
Esto generará una excepción al llamar isset(abc.def.ghi)en caso de que abc.defno esté definido. Sin embargo, al combinar esta solución con la que acepta un nombre de variable en forma de cadena, será idéntica a la versión de PHP.
Steven Pribilinskiy
17
if (!('foo' in obj)) {
  // not set.
}
kennytm
fuente
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;

 } 
//
//
anulación pública
fuente
8

Esta solución simple funciona, pero no para la verificación profunda de objetos.

function isset(str) {
    return window[str] !== undefined;
}
Rodolfo Jorge Nemer Nogueira
fuente
6

Siempre uso esta función genérica para evitar errores en las variables primitivas, así como en matrices y objetos.

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
Innovaat
fuente
5

Si está utilizando subrayado , siempre uso

if (!_.isUndefined(data) && !_.isNull(data)) {
     //your stuff
}
Del
fuente
4

Esta es una solución bastante a prueba de balas para probar si existe una variable:

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

Desafortunadamente, no puede simplemente encapsularlo en una función.

Puede pensar en hacer algo como esto:

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

Sin embargo, esto producirá un error de referencia si la variable variableno se ha definido, porque no puede pasar una variable no existente a una función:

Error de referencia no capturado: foo no está definido

Por otro lado, le permite probar si los parámetros de la función no están definidos:

var a = '5';

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

test(a);

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

Aunque no yse transfiere ningún valor a function test, nuestra issetfunción funciona perfectamente en este contexto, porque yse conoce en la función testcomo un undefinedvalor.

John Slegers
fuente
Nit menor: `? verdadero: falso` es superflous. El resultado de !==ya es un booleano.
ToolmakerSteve
4
(typeof SOMETHING) !== 'undefined'

Es demasiado largo para escribir cuando se usa. Pero no podemos empaquetar la typeofpalabra clave en una función, porque se generará un error antes de que se llame a la función, así:

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

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

Entonces descubrí una manera:

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

isdef(typeof SOMETHING);

Puede funcionar tanto con variables individuales (variables que no existen en absoluto) como con propiedades de objeto (propiedades inexistentes). Y solo 7 caracteres más que PHP isset.

LI XiangChen
fuente
Esto funciona para mí, lo usé para verificar si existía una respuesta json particular.
Julius
3

Esta solución funcionó para mí.

function isset(object){
    return (typeof object !=='undefined');
}
Bastien Viatge
fuente
55
Invocación isset(var)con varunset:ReferenceError: var is not defined
Gui Imamura
3
function isset(variable) {
    try {
        return typeof eval(variable) !== 'undefined';
    } catch (err) {
        return false;
    }
}
Filipe Sarturi
fuente
44
agregue alguna descripción también.
Shree Krishna
Como han mencionado varias respuestas anteriores, esto arrojará un ReferenceError si se llama con una variable que nunca se ha declarado. Por ejemplo isset(someVar), donde someVarnunca ha sido declarado. Sin embargo, dado que lo hace eval, probablemente intente pasar una cadena . Mostrar uso. ¿Es su uso previsto isset('someVar')? Si es así, esto se parece a esta respuesta anterior : ¿qué pasa con su respuesta es nueva?
ToolmakerSteve
3
window.isset = function(v_var) {
    if(typeof(v_var) == 'number'){ if(isNaN(v_var)){ return false; }}
    if(typeof(v_var) == 'undefined' || v_var === null){ return false;   } else { return true; }
};

más pruebas:

https://gist.github.com/daylik/24acc318b6abdcdd63b46607513ae073

Oleg Meshaev
fuente
Como han mencionado varias respuestas anteriores, esto arrojará un ReferenceError si se llama con una variable que nunca se ha declarado.
ToolmakerSteve
3

Para verificar si el bloque html existe o no, estoy usando este código:

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

Proporcione la ruta del objeto como una cadena, luego puede dividir esta cadena en una ruta y resolverla hasOwnPropertyen cada paso mientras sobrescribe el objeto en cada iteración.

Si está codificando en el entorno ES6, eche un vistazo a este Ques de stackoverflow .

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

Gajus
fuente
2

Yo uso una función que puede verificar variables y objetos. muy conveniente para trabajar con jQuery

    function _isset (variable) {
        if(typeof(variable) == "undefined" || variable == null)
            return false;
        else
            if(typeof(variable) == "object" && !variable.length) 
                return false;
            else
                return true;
    };
Евгений Кичаев
fuente
Como han mencionado varias respuestas anteriores, esto arrojará un ReferenceError si se llama con una variable que nunca se ha declarado.
ToolmakerSteve
1

Fue realmente un problema para mí cuando estaba accediendo a una propiedad más profunda de un objeto, por lo que hice una función que devolverá el valor de la propiedad si existe, de lo contrario, devolverá falso. Puede usarlo para ahorrar tiempo,

//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
bikash.bilz
fuente
1

Si desea verificar si existe un elemento, simplemente use el siguiente código:

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

Esta es una muestra:

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>

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

El manual de PHP dice:

isset : determina si una variable está establecida y no es NULL

E interfaz algo como esto:

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

El parámetro $vares la variable a verificar. Sin embargo, puede tener cualquier número de parámetros.

isset () devuelve TRUEsi var existe y tiene un valor diferente a NULL. FALSEde otra manera.

Algun ejemplo:

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

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

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

Como esto en mente, aparentemente, no es posible escribir el equivalente exacto de la isset()función php . Por ejemplo cuando llamamos así:

if (isset(some_var)) {

}

function issset() {
    // function definition
}

Javascript trigger Uncaught ReferenceError: some_var is not defined at (file_name):line_number. Lo importante y notable de este comportamiento es que cuando se intenta pasar variables inexistentes a funciones normales, se desencadena un error.

Pero en PHP isset()no son funciones regulares sino construcciones de lenguaje. Eso significa que son parte del lenguaje PHP en sí, no se rigen por las reglas normales de las funciones y, por lo tanto, pueden salirse con la suya al no desencadenar un error para las variables inexistentes. Esto es importante cuando se trata de averiguar si una variable existe o no. Pero en javscript, desencadena un error en primer lugar, digamos llamada a función con variables inexistentes.

Mi punto es que no podemos escribirlo como una función equivalente de javscript, pero podemos hacer algo como esto

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

Si desea exactamente el mismo efecto, PHP también verifique que varable no sea NULL

Por ejemplo

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

Por lo tanto, podemos incorporar esto en JavaScript y luego se verá así:

if (typeof some_var !== 'undefined' && some_var !== null) {
   // your code here
}
Arjun Kariyadan
fuente
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
Алексей Арх
fuente
0

Tenga cuidado en ES6 , todas las soluciones anteriores no funcionan si desea verificar una declaración de una variable let y declararla, si no es así

ejemplo

let myTest = 'text';

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

verás un error

SyntaxError no capturado: el identificador 'myTest' ya se ha declarado

La solución fue cambiarlo por una var

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

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

otra solución si puede cambiar un let por un var, necesita eliminar su var

let myTest = 'text';

if(typeof myTest === "undefined") {
    myTest = 'new text'; // I remove the var declaration
}
Laurent Chaloupe
fuente
-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;
        }
    }
Vano
fuente