Setter 函数用于动态访问数组中的字段,该数组是一个属性
Setter function to dynamically access fields within an array which is a property
我有一个表示物理模型的javascript模块,其数据在数据对象中提供。此模块导出一个 setter 函数以设置数据对象的属性(注意:在下面的示例中删除了导出(
这在顶层层次结构级别上非常有效,但是如何在属性中设置特定值,例如数组属性的特定字段?
var modeldata = {
current: 100,
pipeline: [150,200,210,220]
}
set = (variable, val) => {
if (modeldata[variable] == undefined) {
console.log('modeldata['+variable+'] is not defined');
} else {
if (modeldata[variable] == val) {
console.log('no change necessary');
} else {
var old = modeldata[variable];
modeldata[variable] = val;
console.log('changing modeldata['+variable+']: ' + old + ' to ' + modeldata[variable])
}
}
}
set('curren', 100); // modeldata[curren] is not defined, OK
set('current', 100); // no change necessary, OK
set('current', 120); // changing modeldata[current]: 100 to 120, OK
set('pipeline[0]', 42); // modeldata[pipeline[0]] is not defined, FAIL
如何使set
函数问题modeldata['pipeline'][0] = 42;
,但仍允许设置current
属性,因为它现在工作?
我可以简单地为每个属性创建一个特定的 setter,但我有 100 个属性>并且属性的数量不是固定的。
此外,我可以调用set('pipeline', ...)
并简单地覆盖整个数组,包括新数据。但如上所述,我只想更改数组的特定字段,而不知道或触摸其他所有内容。
更新:我正在寻找一种解决方案,其中modeldata
仅在set
函数中访问,并且没有可用的get
函数。因此,set
是我唯一的界面 modeldata
.
这是对 set 函数的编辑,以允许数组和子属性更改:
set = (variable, val) => variable.split('.').reduce((prev, curr, i, arr) => {
if (i === arr.length - 1) {
if (prev[curr] == undefined) {
console.log('modeldata[' + variable + '] is not defined');
} else {
if (prev[curr] == val) {
console.log('no change necessary');
} else {
var old = prev[curr];
prev[curr] = val;
console.log('changing modeldata[' + variable + ']: ' + old + ' to ' + prev[curr]);
return prev[curr];
}
}
} else {
return prev[curr];
}
}, modeldata)
你将拥有
set('curren', 100); // modeldata[curren] is not defined, OK
set('current', 100); // no change necessary, OK
set('current', 120); // changing modeldata[current]: 100 to 120, OK
set('pipeline.0', 42); // changing modeldata[pipeline.0]: 150 to 42, OK
走这条路就行了。
var modeldata = {
current: 100,
pipeline: [150, 200, 210, 220]
}
function set(variable, val) {
var path = variable.replace(/'[('d+)']/g, '.$1').split('.'),
target = path.pop(),
reference = path.reduce(function (r, k) { return r[k]; }, modeldata);
if (target in reference) {
if (reference[target] === val) {
alert(variable + ' = ' + val + ''nno change necessary');
} else {
reference[target] = val;
}
} else {
alert(variable + ' is not defined');
}
}
set('curren', 100); // modeldata[curren] is not defined, OK
set('current', 100); // no change necessary, OK
set('current', 120); // changing modeldata[current]: 100 to 120, OK
set('pipeline[0]', 42); // changing modeldata[pipeline.0]: 150 to 42, OK
document.write('<pre>' + JSON.stringify(modeldata, 0, 4) + '</pre>');
我通过在 set
-function 的最开头添加此代码创建了一个快速而肮脏的解决方法:
set = (variable, val) => {
if (variable.indexOf('[')>0 && variable.indexOf(']')>0) {
var old = eval('modeldata.'+variable);
eval('modeldata.'+variable+'='+val);
console.log('changing modeldata.'+variable+': ' + old + ' to ' + val)
return;
}
它有效,但使用eval()
感觉并不好。我很想看到更好的答案。
您可以参考以下代码:
var getBothIndexVariables = function (input) {
var openingIndex = input.indexOf('[');
var secondVal = "";
var indexVariable;
if (openingIndex != -1) {
secondVal = input.substring(openingIndex + 1, input.length - 1);
indexVariable = {
firstIndexVariable: input.substring(0,openingIndex),
secondIndexVariable: secondVal,
}
}
return indexVariable;
}
var modeldata = {
current: 100,
pipeline: [150, 200, 210, 220]
}
set = (variable, val) => {
var tempVariable = getBothIndexVariables(variable);
if (tempVariable) {
debugger;
var value = modeldata[tempVariable.firstIndexVariable][tempVariable.secondIndexVariable];
modeldata[tempVariable.firstIndexVariable][tempVariable.secondIndexVariable] = val;
console.log(value);
return;
}
if (modeldata[variable] == undefined) {
console.log('modeldata[' + variable + '] is not defined');
} else {
if (modeldata[variable] == val) {
console.log('no change necessary');
} else {
var old = modeldata[variable];
modeldata[variable] = val;
console.log('changing modeldata[' + variable + ']: ' + old + ' to ' + modeldata[variable])
}
}
}
set('curren', 100); // modeldata[curren] is not defined, OK
set('current', 100); // no change necessary, OK
set('current', 120); // changing modeldata[current]: 100 to 120, OK
set('pipeline[0]', 42); // modeldata[pipeline[0]] is not defined, FAIL
此条件if (modeldata[variable] ....
检查对象中是否存在不同的命名属性modeldata
。
扩展函数set
以便它可以考虑数组键:
var modeldata = {
current: 100,
pipeline: [150,200,210,220]
}
var set = (variable, val, array_key) => {
var prop = (typeof array_key == "number")? modeldata[variable][array_key] : modeldata[variable];
if (prop == undefined) {
console.log('modeldata['+variable+'] is not defined');
} else {
if (prop == val) {
console.log('no change necessary');
} else {
var old = prop;
if (typeof array_key == "number"){
modeldata[variable][array_key] = val;
} else {
modeldata[variable] = val;
}
console.log('changing modeldata['+variable+']: ' + old + ' to ' + modeldata[variable])
}
}
};
set('curren', 100); // modeldata[curren] is not defined, OK
set('current', 100); // no change necessary, OK
set('current', 120); // changing modeldata[current]: 100 to 120, OK
set('pipeline', 42, 0); // m
console.log(modeldata);
// the output:
Object {current: 120, pipeline: Array[4]} .....
current: 120
pipeline: Array[4]
0: 42
1: 200
2: 210
3: 220
length: 4
相关文章:
- 如何筛选对象的数组属性
- 如何在mongodb(mongose)中覆盖子文档的数组属性
- 如何按对象数组中的数组属性进行筛选
- 基于其他属性查询多维数组属性
- 循环访问 JS 数组 + 数组属性
- AngularJS:观察数组属性
- JSON对象中的数组属性通过foreach更新-更新所有键
- Javascript - 使用数组属性定义对象
- Ember.js with EmberFire Object - 如何使用数组属性
- 我无法访问由开发人员工具中可见的回调填充的 javascript 对象数组属性内容
- 设置对象数据结构数组属性
- 按子数组属性/值对 JavaScript 对象数组进行排序
- 对象的数组属性
- 如何访问 JavaScript 对象上的数组属性
- 使用 jQuery 深层复制对象数组属性值
- 访问并迭代模板内Kendo UI Listview的数组属性
- 主干模型数组属性更改和更改事件侦听器不总是启动
- 在json数组属性中循环
- 通过js中的数组属性方法进行迭代
- 无法清除主干模型数组属性