【问题标题】:Replacing object's properties with properties from another object in JavaScript, without libraries用 JavaScript 中另一个对象的属性替换对象的属性,无需库
【发布时间】:2012-07-25 09:28:20
【问题描述】:

我一直在使用 jQuery.extend 来替换像这样的默认属性

var Car = function(options){
    var defaultOptions = {
        color: "hotpink",
        seats: {
            material: "fur",
            color: "black",
            count: 4
        },
        wheels: 4
    }
    this.options = $.extend(true,{},defaultOptions,options); 
}

var myCar = new Car({
    color: "blue",
    seats: {
        count: 2,
        material: "leather"
    }
});

alert(myCar.options.color); // "blue"
alert(myCar.options.seats.color); // "black"
alert(myCar.options.seats.count); // 2

虽然效果很好,但我想知道在没有任何库的情况下实现类似结果的最佳方法。我只想在函数中定义一些默认设置并用参数中的设置替换它们,每次这样做时都包含一个库是一种矫枉过正。

【问题讨论】:

    标签: javascript object properties default extend


    【解决方案1】:

    基本上它只是for..in 的递归使用。你可以看到 jQuery 实现的完整源代码in the source code(上面的行号会随着时间的推移而腐烂,但它很可能会保留在core.js 中)。

    这是一个非常基本的即兴表演:

    function deepCopy(src, dest) {
        var name,
            value,
            isArray,
            toString = Object.prototype.toString;
    
        // If no `dest`, create one
        if (!dest) {
            isArray = toString.call(src) === "[object Array]";
            if (isArray) {
                dest = [];
                dest.length = src.length;
            }
            else { // You could have lots of checks here for other types of objects
                dest = {};
            }
        }
    
        // Loop through the props
        for (name in src) {
            // If you don't want to copy inherited properties, add a `hasOwnProperty` check here
            // In our case, we only do that for arrays, but it depends on your needs
            if (!isArray || src.hasOwnProperty(name)) {
                value = src[name];
                if (typeof value === "object") {
                    // Recurse
                    value = deepCopy(value);
                }
                dest[name] = value;
            }
        }
    
        return dest;
    }
    

    【讨论】:

    • 如果 OP 想要保留 API,那么 jQuery 是一个好的开始,但如果 OP 准备更改(简化)API,则专门构建的扩展可以更短、更高效和更健壮(例如,jQuery isPlainObject 非常普通且没有必要,isFunctionisArray 也不是)。
    • 正如 RobG 所说,jQuery 的实现似乎是相当多的代码。我想知道是否有任何解决方法或其他方法来解决这个问题。
    • 我正在尝试制作一个易于使用的独立代码sn-p,它基本上只是一个函数,里面有几个方法。有点像 jQuery 插件,但不依赖于 jQuery。为了代码的可读性,我想让用户在单个对象中定义所有选项,但我想为所有内容定义默认值,因此如果用户对默认外观和功能。
    • @user1463028:我只是把 jQuery 作为一个相当彻底的版本的例子,它在大量使用中幸存下来。基本点是它只是for..in 的递归使用。我添加了一个非常基本的,但为什么不使用经过彻底测试的东西呢?是的,理解和取消选择需要更多时间,但是... :-) 最好,
    【解决方案2】:

    你可以模仿jQuery的api“扩展”,就像楼上说的。我认为没有更好的方法可以做到这一点。所以,我觉得jQuery的api是合适的。

    【讨论】:

      【解决方案3】:

      在 ES6 中引入了扩展运算符。

      var Car = function(options){
          var defaultOptions = {
              color: "hotpink",
              seats: {
                  material: "fur",
                  color: "black",
                  count: 4
              },
              wheels: 4
          }
          this.options = {...defaultOptions, ...this.options};
      }
      
      var myCar = new Car({
          color: "blue",
          seats: {
              count: 2,
              material: "leather"
          }
      });
      

      参考资料:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-08-18
        • 2018-03-11
        • 1970-01-01
        • 1970-01-01
        • 2020-06-22
        • 2011-03-11
        • 2016-07-18
        相关资源
        最近更新 更多