JavaScript isset()等价

Bar*_*lom 528 javascript isset

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

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

从更广泛的意义上讲,JavaScript处理不存在的变量,没有值的变量等的一般完整指南会很方便.

CMS*_*CMS 896

我一般使用typeof运营商:

if (typeof obj.foo !== 'undefined') {
  // your code here
}
Run Code Online (Sandbox Code Playgroud)

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

(另见:两者之间的差异undefined和未定义的差异.)

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

if (obj.hasOwnProperty('foo')) {
  // your code here
}
Run Code Online (Sandbox Code Playgroud)

in运营商:

if ('foo' in obj) {
  // your code here
}
Run Code Online (Sandbox Code Playgroud)

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

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

var obj = { foo: 'bar'};

obj.hasOwnProperty('foo'); // true
obj.hasOwnProperty('toString'); // false
'toString' in obj; // true
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,hasOwnProperty返回falsein操作符true在检查toString方法时返回,此方法在原型链中定义,因为obj继承了表单Object.prototype.

  • 这个问题是当你尝试检查更深层的属性时会出现错误,例如:obj.thisdoesntexist.foo!== undefined.在PHP中,您可以在任何深度使用isset或empty并安全地使用. (34认同)
  • 为什么使用`typeof`而不是`if(obj.foo!== undefined)`? (21认同)
  • 确切地说,PHP允许`isset($ abc-> def-> ghi-> jkl)`而不会引发异常并停止脚本,这与JavaScript的`typeof`运算符不同.你必须使用像`try {abc.def.ghi.jkl; isset = true} catch(e){isset = false}` (12认同)
  • 啊.有一天,我会写一段真正的跨浏览器的Javascript.直到那时... (6认同)
  • IE8没有"hasOwnPropery" (6认同)
  • http://jsperf.com/isset-trycatch-vs-loop这有点复杂.`try-catch`方法非常不对称.如果失败,则慢1000(是,千).循环方法不会受到这种不对称性的影响并且表现良好. (2认同)
  • @AlexeyKosov幸运的是,严格模式可以防止分配给`undefined`。 (2认同)

Eno*_*nom 36

古老的线程,但这是一种运行等效的新方法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
Run Code Online (Sandbox Code Playgroud)

答案功能

/**
 * 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
  }
}
Run Code Online (Sandbox Code Playgroud)

说明

PHP

请注意,在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
Run Code Online (Sandbox Code Playgroud)

JS

在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
Run Code Online (Sandbox Code Playgroud)

更多失败的选择:

// 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
Run Code Online (Sandbox Code Playgroud)

还有一些可以快速实现冗余的工作方案:

// 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
Run Code Online (Sandbox Code Playgroud)

结论

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

  1. 假设您只是检查变量是否未定义,这对某些用例很好,但仍然可以抛出错误
  2. 假设您只是尝试访问顶级属性,这对某些用例来说也没问题
  3. 迫使你使用比PHP更不理想的方法,isset()
    例如isset(some, 'nested.deeper.value')
  4. 使用eval()哪个有效,但我个人避免

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

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

谢谢你的阅读!

  • 这个答案值得我登录并投票 (6认同)
  • 如果可以的话,我会让它接受。 (2认同)

Ija*_*een 24

参考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
}
Run Code Online (Sandbox Code Playgroud)

phpjs.org主要是退休,支持locutus这里是新的链接http://locutus.io/php/var/isset

  • 如果`abc.def`未定义,则在调用`isset(abc.def.ghi)`时会引发异常.但是,通过将此解决方案与以字符串形式接受变量名称的解决方案相结合,它将与PHP版本相同. (6认同)

ken*_*ytm 17

if (!('foo' in obj)) {
  // not set.
}
Run Code Online (Sandbox Code Playgroud)


pub*_*ide 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;

 } 
//
//
Run Code Online (Sandbox Code Playgroud)


Rod*_*ira 8

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

function isset(str) {
    return window[str] !== undefined;
}
Run Code Online (Sandbox Code Playgroud)


Inn*_*aat 6

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

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
Run Code Online (Sandbox Code Playgroud)


Bas*_*tge 5

这个解决方案对我有用。

function isset(object){
    return (typeof object !=='undefined');
}
Run Code Online (Sandbox Code Playgroud)

  • 在未设置 `var` 的情况下调用 `isset(var)`:`ReferenceError: var is not defined` (5认同)

Del*_*Del 5

如果您使用的是下划线,我总是使用

if (!_.isUndefined(data) && !_.isNull(data)) {
     //your stuff
}
Run Code Online (Sandbox Code Playgroud)