【问题标题】:Javascript defineProperty vs dynamic property definition behavior explanationJavascript defineProperty vs 动态属性定义行为解释
【发布时间】:2018-03-01 03:45:44
【问题描述】:

Object.defineProperty(obj, 'x', ...)obj.x 有什么区别?

来自MDN,在非严格模式下:

var obj = { }; 
Object.preventExtensions(obj); 

Object.defineProperty(obj, 
  'x', { value: "foo" }
);

抛出错误无法添加属性 x,对象不可扩展。但是obj.x = 'foo' 不会抛出任何错误。我不明白行为上的差异。

【问题讨论】:

标签: javascript readonly


【解决方案1】:

这两种技术都行不通。

您所看到的只是尝试在已调用 .preventExtensions 的对象上调用 .defineProperty 会引发错误,并且当您使用 obj.x = foo 的隐式语法时,它会静默失败。当您未处于严格模式时,静默故障会经常发生,这是"use strict" 的主要优点之一。

在 ES 2015 中添加了许多静态 Object 方法(.preventExtensions.freeze.seal 等)以及 "use strict",以帮助将 JavaScript 带入现代时代。有了这些新功能,我们离 JavaScript 从一开始就存在的一些原生行为越来越远。

"use strict"
var obj = { }; 
Object.preventExtensions(obj); 

// This won't work no matter what mode your in. "use strict" will
// at least make it throw an error rather than silently fail.
obj.x = "foo";

此外,使用 .defineProperty,除了属性值之外,您还可以配置 3 项其他内容:

  • 可配置
  • 可枚举
  • 可写

当您使用object.property = foo 创建新属性时,您只需设置值并获取其他 3 个配置的默认值。

【讨论】:

  • +1 ,正如您所提到的,分配似乎默默地失败了。我检查了 obj.x 的值,它显示未定义。我检查了 Object.getOwnPropertyNames(obj) 和 Object.keys(obj) 以进行验证。它们都没有显示“x”属性。
  • @randominstanceOfLivingThing 完全正确。而且,我上面的代码 sn-p 也显示了这一点。它只是在严格模式下执行,因此您不必追逐 undefined 值。
【解决方案2】:

如果可以向其添加新属性,则对象是可扩展的。 Object.preventExtensions() 将对象标记为不再可扩展,因此它永远不会具有超出它被标记为不可扩展时的属性。请注意,不可扩展对象的属性通常仍可能被删除。尝试向不可扩展的对象添加新属性将失败,静默或抛出TypeError(最常见但不限于strict模式)。

【讨论】:

    猜你喜欢
    • 2019-06-04
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 2019-12-01
    • 2018-03-07
    相关资源
    最近更新 更多