问题描述
- 在给对象中的引用对象继续定义时候的失效问题
附上代码
var obj = {};
function defineObj(obj, key, v) {
Object.defineProperty(obj, key, {
set: function (newv) {
console.log("set",this);
v = newv;
},
get: function () {
console.log("get",this);
return v;//疑点在这里,现在是形参传入进来形成闭包,实现了私有的持久化变量
}
})
}
defineObj(obj,"data",{num:111});
defineObj(obj.data,"num",222);
console.log("----------------------------------------------------------------");
console.log("result:",obj.data.num);
而这样连续给内部引用对象赋值,调用最终对象的值,就会打印出访问这个值所需要的引用步骤数目的get
如上,obj.data---1次 obj.data.num---两次
实际记录这个次数主要为了验证给obj.data定义属性num是否生效,如上是可以的
但是如果把代码改成这样
var obj = {};
function defineObj(obj, key, v) {
Object.defineProperty(obj, key, {
set: function (newv) {
console.log("set",this);
v = newv;
},
get: function () {
console.log("get",this);
return {num:333};//在get中强制返回定义好的对象字面量
}
})
}
defineObj(obj,"data",{num:111});
defineObj(obj.data,"num",222);//没生效
console.log("----------------------------------------------------------------");
console.log("result:",obj.data.num);
而这时返回的结果是
如上,再次给obj.data定义num这一步并没有生效,也就是说一旦在get中返回了声明好的字面量,那后续对这个字面量的扩展就无效了,所以想问下这个是什么原因
自己理解的可能原因:
-
一 因为defineProperty使用访问器描述符创建属性的时候,使用set和get,而定义的这个参数需要set和get都能访问到,类似上面第一段代码中形参v,意思就是我我可拿到这个v给你赋值,也可以给你返回(感觉有些牵强)
defineProperty文档中:
- 二 obj.data.num这个属性的描述configurable是否可以继续定义set和get
var obj = {};
function defineObj(obj, key, v) {
Object.defineProperty(obj, key, {
set: function (newv) {
console.log("set",this);
v = newv;
},
get: function () {
console.log("get",this);
return v;
}
})
}
defineObj(obj,"data",{num:111});
console.log("属性描述:",Object.getOwnPropertyDescriptor(obj.data,"num"));
defineObj(obj.data,"num",222);
console.log("----------------------------------------------------------------");
console.log("result:",obj.data.num);
var obj = {};
function defineObj(obj, key, v) {
Object.defineProperty(obj, key, {
set: function (newv) {
console.log("set",this);
v = newv;
},
get: function () {
console.log("get",this);
return {num:333};
}
})
}
defineObj(obj,"data",{num:111});
console.log("属性描述:",Object.getOwnPropertyDescriptor(obj.data,"num"));
defineObj(obj.data,"num",222);
console.log("----------------------------------------------------------------");
console.log("result:",obj.data.num);
两种定义方式num的属性描述都一样。。。。
第二种情况的defineObj(obj.data,"num",222);js内部执行了这句话,之所以你访问obj.data.num的时候输出的是333,跟你定义obj.data时的get方法有关。