JavaScript isset() 等效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2281633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:35:59  来源:igfitidea点击:

JavaScript isset() equivalent

javascriptisset

提问by Bart van Heukelom

In PHP you can do if(isset($array['foo'])) { ... }. In JavaScript you often use if(array.foo) { ... }to do the same, but this is not exactly the same statement. The condition will also evaluate to false if array.foodoes exists but is falseor 0(and probably other values as well).

在 PHP 中你可以做到if(isset($array['foo'])) { ... }。在 JavaScript 中,您经常使用if(array.foo) { ... }相同的语句,但这并不是完全相同的语句。如果array.foo确实存在但是是falseor 0(也可能是其他值),条件也将评估为 false 。

What is the perfect equivalent of PHP's issetin JavaScript?

什么是issetJavaScript中 PHP 的完美等价物?

In a broader sense, a general, complete guide on JavaScript's handling of variables that don't exist, variables without a value, etc. would be convenient.

从更广泛的意义上讲,关于 JavaScript 处理不存在的变量、没有值的变量等的通用、完整指南会很方便。

回答by CMS

I generally use the typeofoperator:

我一般使用typeof运算符:

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

It will return "undefined"either if the property doesn't exist or its value is undefined.

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

(See also: Difference between undefinedand not being defined.)

(另见:和未定义的区别undefined

There are other ways to figure out if a property exists on an object, like the hasOwnPropertymethod:

还有其他方法可以确定对象上是否存在属性,例如hasOwnProperty方法:

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

And the inoperator:

in运营商:

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

The difference between the last two is that the hasOwnPropertymethod will check if the property exist physicallyon the object (the property is not inherited).

后两者的区别在于该hasOwnProperty方法将检查该属性是否物理存在于对象上(该属性不是继承的)。

The inoperator will check on all the properties reachable up in the prototype chain, e.g.:

in运营商将检查所有属性在原型链,如到达了:

var obj = { foo: 'bar'};

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

As you can see, hasOwnPropertyreturns falseand the inoperator returns truewhen checking the toStringmethod, this method is defined up in the prototype chain, because objinherits form Object.prototype.

如您所见,检查方法时hasOwnProperty返回falsein运算符返回,该方法定义在原型链中,因为继承了 form 。truetoStringobjObject.prototype

回答by Enom

Age old thread, but there are new ways to run an equivalent isset().

古老的线程,但有新方法可以运行等效的isset().

ESNext (Stage 4 December 2019)

ESNext(2019 年 12 月 4 日第 4 阶段)

Two new syntax allow us to vastly simplify the use of isset()functionality:

两种新语法使我们能够极大地简化isset()功能的使用:

Please read the docs and mind the browser compatibility.

请阅读文档并注意浏览器兼容性。

Previous Answer

上一个答案

See below for explanation. Note I use StandardJS syntax

请参阅下面的说明。注意我使用 StandardJS 语法

Example Usage

示例用法

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

Answer 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
  }
}


Explanation

解释

PHP

PHP

Note that in PHP you can reference any variable at any depth - even trying to access a non-array as an array will return a simple trueor false:

请注意,在 PHP 中,您可以在任何深度引用任何变量 - 即使尝试访问非数组作为数组也将返回一个简单的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

JS

In JavaScript, we don't have that freedom, we'll always get an error if we do the same because JS is immediately attempting to access the value of deeperbefore we can wrap it in our isset()function so...

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

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

More failing alternatives:

更多失败的选择:

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

And some working alternatives that can get redundant fast:

以及一些可以快速变得多余的工作替代方案:

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

Conclusion

结论

All of the other answers - though most are viable...

所有其他答案-尽管大多数都是可行的...

  1. Assume you're only checking to see if the variable is not undefined which is fine for some use cases but can still throw an Error
  2. Assume you're only trying to access a top level property, which again is fine for some use cases
  3. Force you to use a less than ideal approach relative to PHP's isset()
    e.g. isset(some, 'nested.deeper.value')
  4. Use eval()which works but I personally avoid
  1. 假设您只是检查变量是否未定义,这对于某些用例来说很好,但仍然会引发错误
  2. 假设您只是尝试访问顶级属性,这对于某些用例来说同样适用
  3. 强制您使用相对于 PHP 的不太理想的方法,isset()
    例如isset(some, 'nested.deeper.value')
  4. 使用eval()哪个有效,但我个人避免

I think I covered a lot of it. There are some points I make in my answer that I don't touch upon because they - although relevant - are not part of the question. If need be, though, I can update my answer with links to some of the more technical aspects based on demand.

我想我涵盖了很多。我在回答中提出了一些我没有涉及的观点,因为它们 - 尽管相关 - 不是问题的一部分。不过,如果需要,我可以根据需求使用指向一些更技术方面的链接来更新我的答案。

I spent waaay to much time on this so hopefully it helps people out.

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

Thank-you for reading!

感谢您的阅读!

回答by Ijas Ameenudeen

Reference to 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 is mostly retired in favor of locutus Here is the new link http://locutus.io/php/var/isset

phpjs.org 大部分已退休,转而支持 locutus 这是新链接http://locutus.io/php/var/isset

回答by kennytm

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

回答by public override

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

 } 
//
//

回答by Rodolfo Jorge Nemer Nogueira

This simple solution works, but not for deep object check.

这个简单的解决方案有效,但不适用于深度对象检查。

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

回答by Innovaat

I always use this generic function to prevent errrors on primitive variables as well as arrays and objects.

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

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

回答by Del

If you are using underscorejsI always use

如果您使用underscorejs我总是使用

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

回答by John Slegers

This is a pretty bulletproof solution for testing if a variable exists :

这是用于测试变量是否存在的非常可靠的解决方案:

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

Unfortunately, you cannot simply encapsulate it in a function.

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

You might think of doing something like this :

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

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

However, this will produce a reference error if variable variablehas not been defined, because you cannot pass along a non-existing variable to a function :

但是,如果变量variable尚未定义,这将产生引用错误,因为您不能将不存在的变量传递给函数:

Uncaught ReferenceError: foo is not defined

未捕获的 ReferenceError: foo 未定义

On the other hand, it does allow you to test whether function parameters are undefined :

另一方面,它确实允许您测试函数参数是否未定义:

var a = '5';

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

test(a);

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

Even though no value for yis passed along to function test, our issetfunction works perfectly in this context, because yis known in function testas an undefinedvalue.

即使对于没有价值y被一起传递给函数test,我们的isset功能完美的作品在这方面,因为y在功能上被称为test作为一个undefined值。

回答by LI XiangChen

(typeof SOMETHING) !== 'undefined'

It's too long to write when used. But we can't package the typeofkeyword into a function, because an error will thrown before the function is called, like this:

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

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

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

So I figured out a way:

于是我想了一个办法:

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

isdef(typeof SOMETHING);

It can work both with individual variables (variables that does not exist at all), or object properties (non-existent properties). And only 7 more characters than PHP isset.

它既可以处理单个变量(根本不存在的变量),也可以处理对象属性(不存在的属性)。并且仅比 PH​​P 多 7 个字符isset