【问题标题】:Initialization of a JavaScript/ES5 object using a constructor with Getter/Setter使用带有 Getter/Setter 的构造函数初始化 JavaScript/ES5 对象
【发布时间】:2018-07-06 03:02:04
【问题描述】:

下面的构造函数是用 JavaScript / ES5 编写的——

function Range(from, to) {

    function getFrom() { return from; }
    function getTo() { return to; }

    function setFrom(f) { from = f; }
    function setTo(t) { to = t; }

    Object.defineProperties(this, {
        fromProp: { get: getFrom, set: setFrom, enumerable: true, configurable: false },
        toProp: { get: getTo, set: setTo, enumerable: true, configurable: false }
    });
};

我使用这个构造函数创建一个对象如下 -

var range = new Range(4, 13);  

我对对象创建的一般理解是,构造函数内部应该有一些代码,在实例化对象range之后,将使用我通过参数传递给构造函数的值初始化fromProp和toProp。但我很难理解这到底是怎么发生的。

或者,这里的整个“初始化/访问属性”是在 setter/getter 调用的闭包中捕获的吗?但如果是这样,那么在我使用的任何时候 -

range.fromProp = 22;

值 22 实际上永远不会设置为range 对象的属性fromProp,而是设置为参数变量from,然后每当我要求时 -

var fromValue = range.fromProp;

它只是将参数变量from 的当前值交给我。我做对了吗,还是遗漏了什么?

对此事有何解释?

【问题讨论】:

  • 属性描述符的属性之一是value; developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。而且我觉得你使用这些 getter 和 setter 让你自己太难了,因为它们似乎并没有真正做任何特别的事情。
  • 是的,这都是对参数的闭包。您可以通过例如轻松地测试它。关闭另一个函数中的参数,使其可在外部访问(例如,通过将其设置为全局变量以进行测试),并使用该函数更改属性:let changer; function Range(from, to) { changer = x => { from = x }; /* rest of constructor as you wrote it */ }; var range = new Range(4, 13); changer(999); console.log(range.fromProp);
  • @HereticMonkey,它们似乎为您的对象的内部状态提供了很好的封装:)
  • @MarkMeyer,我没有说代码不起作用。如果您理解我的意思,我的问题是基于“了解它的工作方式”。 fromValue 拥有 22,但问题是,它永远不会从 range 对象的 fromProp 属性中获取该值,而是从构造函数的 from 参数变量中获取该值:)
  • fromProp 不是数据属性,而是accessor property。 property accessor operator(在本例中为 range.fromProp 中的 .,不要与访问器属性混淆)调用访问器属性的 getter 函数,该函数将值从作用域访问解析为构造函数中的 from 参数.

标签: javascript constructor ecmascript-5 object-initialization


【解决方案1】:
function Range(from, to) {

function getFrom() { return from; }
function getTo() { return to; }

function setFrom(f) { from = f; }
function setTo(t) { to = t; }

Object.defineProperties(this, {
    fromProp: { get: getFrom, set: setFrom, enumerable: true, configurable: false },
    toProp: { get: getTo, set: setTo, enumerable: true, configurable: false }
});

};

让我们在这里分析一下,您将“fromProp”的“get”属性设置为“getFrom”函数的引用,您将在其中返回“from”参数的值,并且以相同的方式“set”引用函数“setFrom”正在完成对“from”的赋值。

作为结论,fromProp 的 get 和 set 不是直接持有值,而是持有访问器函数以返回 "from" 的值。

希望你的疑问现在已经清楚了。

【讨论】:

    【解决方案2】:

    如果您来自 Java/C# 世界,那么乍一看这当然有点奇怪,因为在这些语言中,任何通过构造函数参数传递的值通常用于初始化对象,即将值保存为对象的内部状态,通常用私有字段表示。然后这些私有字段通过带有 getter/setter 的属性暴露给外界。

    因此,这些语言中的 getter/setter 实际上封装了对象的内部数据,而不是构造函数参数。

    另一方面,JavaScript 不提供将对象的状态设为私有的能力。

    这就是为什么这里的构造函数参数的值没有保存到任何数据属性中,而是在调用访问器属性的Closure 中捕获(如 cmets 中所述),以模拟对象的私有状态.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-05
      • 1970-01-01
      • 2011-07-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多