更改JavaScript对象
问题描述:
我有此功能:更改JavaScript对象
var changeFilter = (function (filterName, filterValue) {
var filters = {
"tip-oglasa": "",
"zemlja": "",
"grad": "",
"deo-grada": "",
"min-kvadrata": "",
"max-kvadrata": "",
"min-soba": "",
"max-soba": "",
"min-spratova": "",
"max-spratova": "",
"min-godina-izgradnje": "",
"max-godina-izgradnje": ""
};
return function() {
filters[filterName] = filterValue;
return filters;
};
})();
我想在哪个对象filters
将被定义功能,并获得/通过两个功能改变(getFilters
,这将只是获取的过滤器变量和changeFilter
这将更改过滤器变量和返回结果)。
是否有可能做这样的事情?我不想让filters
对象公开,因为我只想通过这两种方法访问它。
答
当然,只是返回一个对象字面与功能,这将作为方法:
var filtersProxy = (function() {
var filters = {
"tip-oglasa": "",
"zemlja": "",
"grad": "",
"deo-grada": "",
"min-kvadrata": "",
"max-kvadrata": "",
"min-soba": "",
"max-soba": "",
"min-spratova": "",
"max-spratova": "",
"min-godina-izgradnje": "",
"max-godina-izgradnje": ""
};
return {
getFilters: function getFilters() {
return filters;
},
changeFilter: function changeFilter(filterName, filterValue) {
filters[filterName] = filterValue;
return filters;
}
};
})();
有几件事情需要注意这个特殊的例子:
-
filtersProxy.getFilters()
将返回一个参考filters
对象,并且对该对象的更改将通过filters
变量反映出来。也就是说,有人可以做filtersProxy.getFilters().foo = 'bar'
并改变它。可能的解决方案:- 返回对象的副本,以便调用者可以更改您提供的对象而不更改
filters
。 - 提供访问者
getFilter(key)
,它返回指定对象属性处的值。
- 返回对象的副本,以便调用者可以更改您提供的对象而不更改
- 与
filtersProxy.changeFilter()
有相同的问题,它返回filters
。在这里你可以只需return this
返回代理对象,并允许链接:filtersProxy.changeFilter('foo', 'bar').changeFilter('bar', 'baz').getFilter('baz')
。 - 我将参数从IIFE移动到
changeFilter
方法,因为这是他们真正属于的地方。 - 考虑到您提供get和set访问器,并且不进行过滤/验证,与直接使用对象相比,以这种方式执行操作没有任何优势,除非您打算在getter和setter中添加一些验证或其他逻辑。
答
当然,例如,你可以有可变“私有”或仅使用var
然后有一个getter和setter改变该变量为你喜欢的功能范围内访问:
function Filter() {
var filters = {
"tip-oglasa": "",
"zemlja": "",
"grad": "",
"deo-grada": "",
"min-kvadrata": "",
"max-kvadrata": "",
"min-soba": "",
"max-soba": "",
"min-spratova": "",
"max-spratova": "",
"min-godina-izgradnje": "",
"max-godina-izgradnje": ""
};
this.setFilter = function(filter, value){
\t filters[filter] = value;
}
this.getFilter = function(){
\t return filters;
}
}
var filter = new Filter();
console.log(Filter.filters); // private, shows undefined
console.log(filter.getFilter()); // show filter
filter.setFilter("grad", "foo"); // set grad filter to "foo"
console.log(filter.getFilter()); // shows updated filter
谢谢!我在我的网页的脚本中使用它,所以我想让整个事情变得更加有组织,并且更容易跟踪/调试,而不需要在全局空间中定义数据(我最后一个项目包含了大量的变量,所以我不想重复同样的错误)。如果我正确地理解了你,你认为我应该在两个返回的方法中使另一个与'filters'相同的变量返回而不是'filters'变量,对吧? – Nikola
@Nikola如果你根本没有防范访问,你应该直接使用数据对象(比如'filters'),而不是隐藏在没有任何好处的对象之后。 – cdhowie
@chdowie,好吧,我实际上打算添加更多功能(除了通过AJAX发送此对象的其他功能外),并且更容易完成而不是更改变量,然后调用单独的函数发送它。 – Nikola