JavaScript isset()等效
在PHP中,你可以这样做if(isset($array['foo'])) { ... }
。 在JavaScript中你经常使用if(array.foo) { ... }
来做同样的事情,但是这不是完全一样的陈述。 如果array.foo
存在但是false
或0
(也可能是其他值),则条件也将计算为false。
JavaScript中isset
的完美等价物是什么?
从更广泛的意义上讲,关于JavaScript处理不存在的variables,无variables的variables等的一般性,完整的指导将很方便。
我通常使用typeof
运算符:
if (typeof obj.foo !== 'undefined') { // your code here }
如果该属性不存在或者其值undefined
,它将返回"undefined"
。
(另请参阅: undefined
和undefined
之间的区别。 )
还有其他方法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
返回false
, in
运算符在检查toString
方法时返回true
,这个方法在原型链中定义,因为obj
inheritanceObject.prototype
forms。
参考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 – 甚至尝试访问非数组作为数组将返回一个简单的true
或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
在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大多数是可行的…
- 假设你只是检查variables是不是未定义的,这对于某些用例来说是好的,但仍然可以抛出一个错误
- 假设你只是试图访问一个顶级的属性,对于一些使用情况来说也是一样的
- 强迫你使用相对于PHP的
isset()
不太理想的方法
例如isset(some, 'nested.deeper.value')
- 使用
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 }