使用带有Getter/Setter的构造函数初始化JavaScript/ES5对象
以下构造函数是用JavaScript/ES5编写的-使用带有Getter/Setter的构造函数初始化JavaScript/ES5对象,javascript,constructor,ecmascript-5,object-initialization,Javascript,Constructor,Ecmascript 5,Object Initialization,以下构造函数是用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, { f
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);
我对对象创建的一般理解是,构造函数中应该有一些代码,在实例化对象范围
后,将使用我通过参数传递给构造函数的值初始化fromProp
和toProp
。但我很难理解这到底是怎么发生的
或者,这里所有的“初始化/访问属性”都是在setter/getter调用的闭包中捕获的吗?但如有,则在我使用—
range.fromProp = 22;
实际上,值22从未设置为范围
对象的属性fromProp
,而是设置为参数变量from
,然后每当我请求-
var fromValue = range.fromProp;
它只是将参数变量的当前值从
传递给我。我做对了,还是遗漏了什么
对这件事有什么解释吗
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”的值
希望你的疑问现在清楚了。如果你来自Java/C世界,那么乍一看,这当然有点奇怪,因为在这些语言中,通过构造函数参数传递的任何值通常用于初始化对象,即将值保存为对象的内部状态,通常用私有字段表示。然后,通过getter/setter属性将这些私有字段公开给外部世界
因此,这些语言中的getter/setter实际上封装了对象的内部数据,而不是构造函数参数
另一方面,JavaScript不提供使其对象的状态为私有的能力
这就是为什么这里的构造函数参数的值没有保存到任何数据属性中,而是在调用访问器属性(如注释中所述)的
闭包中捕获,以模拟对象的私有状态。属性描述符的属性之一是值。我有种感觉,你使用这些getter和setter让这对你自己来说太难了,因为它们似乎没有做任何特殊的事情。是的,所有的参数都是闭包。您可以通过关闭另一个函数中的参数,使其在外部可访问(例如,为了测试目的,将其设置为全局变量),并使用该函数更改属性来轻松测试:let changer;函数范围(从,到){changer=x=>{from=x};/*编写时构造函数的其余部分*/};var范围=新范围(4,13);换碟机(999);console.log(range.fromProp)
@HereticMonkey,它们似乎对对象的内部状态进行了很好的封装:)@MarkMeyer,我没说代码不起作用。如果你理解我的意思,我的问题是基于“了解它的工作方式”fromValue
持有22,但问题是,它从不从range
对象的fromProp
属性获取该值,而是从构造函数的from
参数变量获取:)fromProp
不是一个数据属性,而是一个属性。(在本例中,范围.fromProp
中的
,不要与访问器属性混淆)调用访问器属性的getter函数,该函数解析构造函数中从作用域访问到from
参数的值。