为了账号安全,请及时绑定邮箱和手机立即绑定

等同于JavaScript isset()

等同于JavaScript isset()

茅侃侃 2019-10-14 09:46:27
在PHP中可以做到if(isset($array['foo'])) { ... }。在JavaScript中,您通常会使用if(array.foo) { ... }相同的方法,但这并非完全相同。如果array.foo确实存在但为falseor 0(或可能还有其他值),则条件还将评估为false 。issetJavaScript 与PHP的完美等同是什么?从更广泛的意义上讲,有关JavaScript处理不存在的变量,没有值的变量等的通用完整指南将很方便。
查看完整描述

3 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

使用旧线程,但这是运行等效线程的新方法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

应答功能

/**

 * 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中,您可以引用任何深度的任何变量-甚至尝试访问非数组,因为数组将返回简单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 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

更多失败的选择:


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

结论

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


假设您仅检查变量是否未定义,这在某些用例中可以使用,但仍然会引发错误

假设您仅尝试访问顶级属性,这对于某些用例来说也很好

强迫您使用相对于PHP而言不太理想的方法,isset()

例如isset(some, 'nested.deeper.value')

使用eval()哪种有效,但我个人避免使用

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


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


谢谢您的阅读!


查看完整回答
反对 回复 2019-10-14
  • 3 回答
  • 0 关注
  • 399 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信