【问题标题】:Why does the in operator return true for a property that is undefined?为什么 in 运算符对未定义的属性返回 true?
【发布时间】:2015-06-01 18:39:19
【问题描述】:

说明

我总是错误地认为in 运算符正在检查属性的undefined 值。快速查看ES5 specification 会发现in 运算符最终会调用[[GetProperty]],这将返回属性的值。

为什么当foo.bar设置为undefinedin操作符返回true,而当foo.bar从未设置时它是false,即使它们的值都是undefined?

示例

var foo = {
    bar: undefined
};

'baz' in foo
// -> false

'bar' in foo
// -> true

相关:typeof foo['bar'] !== 'undefined' vs. 'bar' in foo 相关问题是询问何时foo.bar 从未设置为undefined

【问题讨论】:

  • 只检查 prop 是在对象上定义还是在继承的对象上定义,而不是值是什么。

标签: javascript


【解决方案1】:

注意:在研究问题时我找到了答案,因为我已经花了时间,所以我决定发布我发现的内容。


它们返回不同值的原因是[[GetProperty]]调用[[GetOwnProperty]],它没有返回属性值。 [[GetOwnProperty]] 返回一个 Property Descriptor,它描述了属性是否可枚举、可写及其值等内容。

当您将属性设置为undefined(如问题中的bar)时,将创建一个属性描述符*,其中[[Value]]undefined。当为bar 调用[[GetOwnProperty]] 时,将返回属性描述符,而使用baz,则返回undefined。这意味着[[GetProperty]]bar 返回一个定义的值,这使得[[HasProperty]] 返回true,而不是false。这反过来使in 运算符也返回true

* 这是一个谎言,但为了简单起见。

规范跟踪

来自Annotated ECMAScript 5.1

注意:下面的数字尽可能链接到规范参考

发给:'bar' in foo

  • 1. 评估 'bar' 给出一个字符串 'bar'
  • 2. GetValue of 'bar' 将返回值 'bar'
  • 3. 评估 foo 提供参考 foo
  • 4. GetValue of foo 将返回 'foo' 的值,我们的对象
  • foo 的值的5. Type 是一个对象,没有抛出异常
    1. 'bar'的值toString返回字符串'bar,调用[[HasProperty]]
      • 1.[[GetProperty]] 返回Property Descriptor(不是undefined
      • 1.[[GetOwnProperty]]返回属性描述符(不是undefined
        1. foo 确实有自己的属性称为bar,不要返回undefined
        1. 创建一个没有字段的属性描述符
        1. foo.bar 创建 X
        1. X 是一个数据属性,所以将 [[Value]] 设置为undefined 并设置[[Writable]]
        1. 跳过其他分支
        1. 设置 [[Enumerable]]
        1. 设置[[可配置]]
        1. 返回属性描述符
        1. 属性描述符未定义,返回属性描述符。
        1. 属性描述符不是undefined,所以不要返回false
        1. 否则,返回 true

【讨论】:

    猜你喜欢
    • 2021-11-10
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多