javascript - jQuery Plugin - 深度选项修改

标签 javascript jquery jquery-plugins javascript-objects

我目前正在使用一个设置变量相当深的插件(某些地方有 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/

相关文章:

jquery - 模板文字格式/语法问题

jquery - 如何在 Select2 JQuery 插件中定义占位符文本

javascript - jQuery:JS 的延迟加载

javascript - Typescript:如何在全局范围内进行一些导入?

javascript - 如果字符串包含字符,则使用正则表达式模式

javascript - 为什么 array[array.length] 返回未定义?

javascript - jQuery 插件未从 AJAX 返回的 JSON 返回结果

javascript - 如何仅将依赖项放入 yarn 的特定文件夹中?

jquery - 如何使用 jQuery 进行标签切换

javascript - Jquery 在父级之外查找 ID 或表单