Javascript Object.defineProperty复制属性值
我正在试验下面的一些代码,一切似乎都按预期进行。目标是将Javascript Object.defineProperty复制属性值,javascript,this,getter-setter,Javascript,This,Getter Setter,我正在试验下面的一些代码,一切似乎都按预期进行。目标是将a.val绑定到b.val,这样当a.val更改时,b.val也会自动更改 // instantiate var a = {} var b = {} // set value a.val = 10 // check values console.log("A.val is:", a.val) // 10 console.log("B.val is:", b.val) // undefined // bind values Objec
a.val
绑定到b.val
,这样当a.val
更改时,b.val
也会自动更改
// instantiate
var a = {}
var b = {}
// set value
a.val = 10
// check values
console.log("A.val is:", a.val) // 10
console.log("B.val is:", b.val) // undefined
// bind values
Object.defineProperties(a, {
val: {
configurable: true, // can be changed or deleted
enumerable: true, // can be iterated over
get: ()=> this.val,
set: (value)=> {
this.val = value
b.val = value
return value
}
}
})
// reset value
a.val = 20
// check values
console.log("A.val is:", a.val) // 20
console.log("B.val is:", b.val) // 20
所以我想继续这个概念,并将对象.defineProperties
部分抽象为一个函数。我想我可以通过一个对象的属性创建一个for循环和循环,调用object.defineProperty
。但我遇到了一些问题:
function getSet(props){
for(var key in props){
Object.defineProperty(props, key, {
configurable: true, // can be changed or deleted
enumerable: true, // can be iterated over
get: ()=> this[key],
set: (value)=> {
this[key] = value
return value
}
})
}
return props
}
var a = getSet({name: 'the letter a', age: 12})
a.name // undefined
a.name = 'the letter a'
a.age // 'the letter a'
实际上,我无意中绑定了传递给getSet
函数的对象的两个属性。此外,我还删除了它们的初始值
我的问题是,为什么会发生这种情况,以及我如何更接近我的目标,将一个对象的属性绑定到另一个对象
通过测试其他几种可能的解决方案,我遇到了一个
超过最大调用堆栈大小的错误:我假设在getter或setter中引用this
时,从我试图定义属性的对象获取值的行为会触发对getter的调用,并无限期地循环。不完全确定发生这种情况的时间/原因。您当前的代码实际上无法工作。这两个主要缺陷是
- 你。
此
值将是模块对象(在节点中)或全局对象(浏览器中的窗口
),而不是当前对象
- 如果它按照您的预期工作,并且引用了当前访问的接收者(这也是在您尝试适当的方法时发生的),那么您将从
a.val
读取a.val
的值,并将a.val
的值写入a.val
,从而创建您所经历的无限递归。您需要为实际存储使用其他东西-在您的情况下,b
对象是正确的解决方案
- 在浏览器中,指定给全局对象的
name
属性将强制所有内容为字符串
- 在你的循环中,只有一个循环。因此,它们都将在商店的同一位置使用该值
要解决此问题,请使用
function getSet(proxy, store) {
for (const key in store) {
// ^^^^^ block scope
Object.defineProperty(props, key, {
configurable: true,
enumerable: true,
get: () => { return store[key]; },
// ^^^^^
set: (value) => { store[key] = value; }
// ^^^^^
});
}
return proxy;
}
此
与您认为的功能无关。在你的getSet
函数中,这个指的是窗口。@Tibrogargan:你说得对。虽然。这并不能完全解决我的问题。我用var copy=Object.assign({},props)
实现了同样的功能,并用copy
替换了this
。这些属性仍然受到约束。如果我改变年龄
它会改变姓名
,反之亦然。