我有一个闭包我用来设置和检索几个方法需要的对象的状态。
不幸的是我遇到了一些奇怪的行为。在某些情况下,我想修改闭包中返回的信息,同时仍然将闭包中的变量保持在预期的状态。换句话说,我不想使用闭包的set方法,我只想检索对象,进行简短的临时修改,并让闭包为其他任何可能需要信息的方法保持其先前的状态。
然而,这不起作用,我的临时更改导致闭包对象改变,尽管没有使用set方法。我完全承认我不理解范围等级问题。这是代码:
<script>
var closureTest= {
filterState: (function () {
var filterObject = {
'model': 'ford',
'year': '2010'
};
return {
setFilterObject: function (input) {
filterObject.model = input;
},
getFilterObject: function () {
return filterObject;
}
};
})()
};
//lets retrieve the default values
var resultsToModify = closureTest.filterState.getFilterObject();
//now lets attempt to change the model for a one time use
resultsToModify.model = 'chevy';
//now lets grab the object again (assuming it will return ford and
//2010 because we didn't use the setFilterObject method to change the object
var defaultClosureAgain = closureTest.filterState.getFilterObject();
//expected would show model type as chevy
console.log('resultsToModify: ',resultsToModify);
//but why does this show chevy too?
//The setFilterObject was never used to modify the object? what am I missing?
console.log('defaultClosureAgain: ',defaultClosureAgain);
</script>
答案 0 :(得分:0)
在函数外返回getter和setter方法将导致
暴露功能变量。在你的代码中......
return {
setFilterObject: function (input) {
filterObject.model = input;
},
getFilterObject: function () {
return filterObject;
}
};
答案 1 :(得分:0)
以下是对代码的最小更改 - 返回container-id-json.log
的副本。这将允许您在不影响原件的情况下对副本进行更改。原始版本应该只在filterObject
API中公开,这是(我可以收集的)你打算改变该对象的唯一方法。
set
&#13;
注意var closureTest= {
filterState: (function () {
var filterObject = {
'model': 'ford',
'year': '2010'
};
return {
setFilterObject: function (input) {
filterObject.model = input;
},
getFilterObject: function () {
return Object.assign({}, filterObject);
// ---------------------^^^^^^^^^^^^^^^^ copy filterObject
}
};
})()
};
//lets retrieve the default values
var resultsToModify = closureTest.filterState.getFilterObject();
//now lets attempt to change the model for a one time use
resultsToModify.model = 'chevy';
//now lets grab the object again (assuming it will return ford and
//2010 because we didn't use the setFilterObject method to change the object
var defaultClosureAgain = closureTest.filterState.getFilterObject();
//expected would show model type as chevy
console.log('resultsToModify: ',resultsToModify);
//but why does this show chevy too?
//The setFilterObject was never used to modify the object? what am I missing?
console.log('defaultClosureAgain: ',defaultClosureAgain);
仅限ES6 +。您需要使用polyfill或者转发器来获得完整的浏览器支持。
我将补充一点,你在这里玩的范例并没有太多真实世界的应用,很可能有更好的方法来实现最终目标&#34;是,如果有的话。但是,如果你只是在玩耍,那么这总是一件好事!