更改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中添加一些验证或其他逻辑。
+0

谢谢!我在我的网页的脚本中使用它,所以我想让整个事情变得更加有组织,并且更容易跟踪/调试,而不需要在全局空间中定义数据(我最后一个项目包含了大量的变量,所以我不想重复同样的错误)。如果我正确地理解了你,你认为我应该在两个返回的方法中使另一个与'filters'相同的变量返回而不是'filters'变量,对吧? – Nikola

+0

@Nikola如果你根本没有防范访问,你应该直接使用数据对象(比如'filters'),而不是隐藏在没有任何好处的对象之后。 – cdhowie

+0

@chdowie,好吧,我实际上打算添加更多功能(除了通过AJAX发送此对象的其他功能外),并且更容易完成而不是更改变量,然后调用单独的函数发送它。 – Nikola

当然,例如,你可以有可变“私有”或仅使用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