JavaScript isset()等效

在PHP中,你可以这样做if(isset($array['foo'])) { ... } 。 在JavaScript中你经常使用if(array.foo) { ... }来做同样的事情,但是这不是完全一样的陈述。 如果array.foo存在但是false0 (也可能是其他值),则条件也将计算为false。

JavaScript中isset的完美等价物是什么?

从更广泛的意义上讲,关于JavaScript处理不存在的variables,无variables的variables等的一般性,完整的指导将很方便。

我通常使用typeof运算符:

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

如果该属性不存在或者其值undefined ,它将返回"undefined"

(另请参阅: undefinedundefined之间的区别。 )

还有其他方法hasOwnProperty某个对象是否存在属性,如hasOwnProperty方法:

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

in运营商:

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

最后两者之间的区别在于hasOwnProperty方法将检查属性是否物理存在于对象上(该属性未被inheritance)。

in运算符将检查原型链中可到达的所有属性,例如:

 var obj = { foo: 'bar'}; obj.hasOwnProperty('foo'); // true obj.hasOwnProperty('toString'); // false 'toString' in obj; // true 

正如你所看到的, hasOwnProperty返回falsein运算符在检查toString方法时返回true ,这个方法在原型链中定义,因为objinheritanceObject.prototypeforms。

参考SOURCE

 function isset () { // http://kevin.vanzonneveld.net // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + improved by: FremyCompany // + improved by: Onno Marsman // + improved by: Rafał Kukawski // * example 1: isset( undefined, true); // * returns 1: false // * example 2: isset( 'Kevin van Zonneveld' ); // * returns 2: true var a = arguments, l = a.length, i = 0, undef; if (l === 0) { throw new Error('Empty isset'); } while (i !== l) { if (a[i] === undef || a[i] === null) { return false; } i++; } return true; } 
 if (!('foo' in obj)) { // not set. } 
 // // 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; } // // 

这个简单的解决scheme工作,但不是深入的对象检查。

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

我总是使用这个generics函数来防止原始variables以及数组和对象的错误。

 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 

如果你正在使用underscorejs我总是使用

 if (!_.isUndefined(data) && !_.isNull(data)) { //your stuff } 
 function isset(variable) { try { return typeof eval(variable) !== 'undefined'; } catch (err) { return false; } } 

这个解决scheme为我工作。

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

这是testingvariables是否存在的一个非常好的解决scheme:

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

不幸的是,你不能简单地把它封装在一个函数中。

你可能会想到做这样的事情:

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

但是,如果variablesvariable没有被定义,这会产生一个引用错误,因为你不能把一个不存在的variables传递给一个函数:

Uncaught ReferenceError:foo未定义

另一方面,它允许您testing函数参数是否未定义:

 var a = '5'; var test = function(x, y) { console.log(isset(x)); console.log(isset(y)); }; test(a); // OUTPUT : // ------------ // TRUE // FALSE 

尽pipe没有将y值传递给函数test ,但是我们的isset函数在这个上下文中是完美的,因为y在函数test被称为undefined值。

以stringforms提供对象path,然后可以将此string拆分为path,并在每一步中parsinghasOwnProperty ,同时每次迭代覆盖对象本身。

如果你在ES6环境下编码,看看这个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, 'bcd') == false, isset(a, 'bcde') == false, isset(a, 'bcdef') == false ); 
 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; } }; 

加上testing:

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

年龄过时的线程,但是这里有一个新的方法来运行等效的isset()

回答

请参阅下面的解释。 注意我使用StandardJS语法

用法示例

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

应答function

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

说明

PHP

请注意,在PHP中,您可以在任何深度引用任何variables – 甚至尝试访问非数组作为数组将返回一个简单的truefalse

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

在JavaScript中,我们没有这种自由,如果我们这样做,我们总是会得到一个错误,因为JS在我们可以将它包装在我们的isset()函数中之前立即尝试访问deeper的值,所以…

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

更多失败的select:

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

还有一些可以快速获得冗余的工作方式:

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

结论

所有其他答案 – 尽pipe大多数是可行的…

  1. 假设你只是检查variables是不是未定义的,这对于某些用例来说是好的,但仍然可以抛出一个错误
  2. 假设你只是试图访问一个顶级的属性,对于一些使用情况来说也是一样的
  3. 强迫你使用相对于PHP的isset()不太理想的方法
    例如isset(some, 'nested.deeper.value')
  4. 使用eval() ,但我个人避免

我想我涵盖了很多。 我在答复中提出了一些我没有涉及的观点,因为它们虽然相关,但不是问题的一部分。 如果需要的话,我可以根据需求更新我的答案,并链接到一些更技术性的方面。

我花了很多时间在这个,所以希望它可以帮助人们。

感谢您的阅读!

 (typeof SOMETHING) !== 'undefined' 

使用时写入太长。 但是我们不能将typeof关键字打包成一个函数,因为在函数调用之前抛出一个错误,就像这样:

 function isdef($var) { return (typeof $var) !== 'undefined'; } isdef(SOMETHING); ///// thrown error: SOMETHING is not defined 

所以我想出了一个办法:

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

它可以与单个variables(完全不存在的variables)或对象属性(不存在的属性)一起工作。 只有7个字符比PHP更多。

检查是否存在或不存在,我正在使用此代码:

 if (typeof($('selector').html()) != 'undefined') { // $('selector') is existing // your code here } 
 if (var) { // This is the most concise equivalent of Php's isset(). } 

PHP手册说:

isset – 确定是否设置了一个variables,而不是NULL

接口是这样的:

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

参数$var是要检查的variables。 它可以有任何数量的参数。

isset()返回TRUE如果var存在并且具有非NULL 。 否则为FALSE

一些例子:

 $foo = 'bar'; var_dump(isset($foo)); -> true $baz = null; var_dump(isset($baz)); -> false var_dump(isset($undefined)); -> false 

正如这一点,显然,这是不可能写的确切等价的PHP isset()函数。 例如,当我们这样称呼:

 if (isset(some_var)) { } function issset() { // function definition } 

Javascript触发Uncaught ReferenceError: some_var is not defined at (file_name):line_number 。 这种行为的重要和显着的事情是,当试图将不存在的variables传递给正常的函数时,会触发错误。

但是在PHP中, isset()实际上并不是正则函数,而是语言结构。 这意味着它们是PHP语言本身的一部分,不要按照正常的函数规则来玩,因此可以避免为不存在的variables触发错误。 当试图找出variables是否存在时,这很重要。 但是在javscript中,首先触发一个错误,用不存在的variables调用函数。

我的观点是,我们不能把它写成等价的javscript函数,但我们可以做这样的事情

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

如果你想要完全相同的效果PHP也检查可变是不是NULL

例如

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

所以,我们可以将它合并到JavaScript中,然后看起来像这样:

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