我目前正在使用一个设置变量相当深的插件(某些地方有 3-4 个级别)。按照普遍接受的 jQuery 插件模式,我实现了一种简单的方法,供用户使用以下符号即时修改设置:
$('#element').plugin('option', 'option_name', 'new_value');
这是与我现在用于选项方法的代码类似的代码。
option: function (option, value) {
if (typeof (option) === 'string') {
if (value === undefined) return settings[option];
if(typeof(value) === 'object')
$.extend(true, settings[option], value);
else
settings[option] = value;
}
return this;
}
现在考虑我有一个像这样的设置变量:
var settings = {
opt: false,
another: {
deep: true
}
};
如果我想更改 deep
设置,我必须使用以下符号:
$('#element').plugin('option', 'another', { deep: false });
但是,由于在实践中我的设置可能有 3-4 层深,我觉得以下符号会更有用:
$('#element').plugin('option', 'another.deep', false);
但是我不确定这是否可行,也不确定如何去做。作为第一次尝试,我尝试“遍历”到有问题的选项并设置它,但是如果我设置遍历变量,它不会设置它在原始设置变量中引用的内容。
option: function (option, value) {
if (typeof (option) === 'string') {
if (value === undefined) return settings[option];
var levels = option.split('.'),
opt = settings[levels[0]];
for(var i = 1; i < levels.length; ++i)
opt = opt[levels[i]];
if(typeof(value) === 'object')
$.extend(true, opt, value);
else
opt = value;
}
return this;
}
换个说法:通过遍历后设置opt
,这段代码运行后,它在settings
变量中实际引用的设置是不变的。
对于这个冗长的问题,我深表歉意,我们将不胜感激。谢谢!
编辑
作为第二次尝试,我可以像这样使用 eval()
来完成它:
option: function (option, value) {
if (typeof (option) === 'string') {
var levels = option.split('.'),
last = levels[levels.length - 1];
levels.length -= 1;
if (value === undefined) return eval('settings.' + levels.join('.'))[last];
if(typeof(value) === 'object')
$.extend(true, eval('settings.' + levels.join('.'))[last], value);
else
eval('settings.' + levels.join('.'))[last] = value;
}
return this;
}
但我真的很想看看是否有人可以告诉我一种不使用 eval 的方法。因为它是一个用户输入字符串,所以我不想在它上面运行 eval()
因为它可以是任何东西。或者让我知道我是否偏执,这根本不会造成问题。
最佳答案
您在这里遇到的问题归结为指向对象的变量与指向其他类型(如字符串)的变量之间的区别。 2 个变量可以指向同一个Object
,但不能指向同一个String
:
var a = { foo: 'bar' };
var b = 'bar';
var a2 = a;
var b2 = b;
a2.foo = 'hello world';
b2 = 'hello world';
console.log(a.foo); // 'hello world'
console.log(b); // 'bar'
您的遍历代码在循环的最后一次迭代之前一直有效,此时 opt
是一个包含与 deep
相同的值 的变量在对象 settings.opt.another
中。相反,缩短循环并使用 levels
的最后一个元素作为 key
,例如
var settings = {
another: {
deep: true
}
};
var levels = 'another.deep'.split('.')
, opt = settings;
// leave the last element
var i = levels.length-1;
while(i--){
opt = opt[levels.shift()];
}
// save the last element in the array and use it as a key
var k = levels.shift();
opt[k] = 'foobar'; // settings.another.deep is also 'foobar'
在此阶段,opt
是指向与 settings.another
相同的 Object
的指针,k
是一个String
的值为 'deep'
关于javascript - jQuery Plugin - 深度选项修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8420162/