天天看点

underscore 源码阅读【五】createAssigner

createAssigner

createAssigner设计到三个API:

  • _defaults
  • _.extend
  • _.extendOwn

_defaults

var iceCream = {flavor: “chocolate”};

_.defaults(iceCream, {flavor: “vanilla”, sprinkles: “lots”});

=> {flavor: “chocolate”, sprinkles: “lots”}

用defaults对象填充object 中的undefined属性。 并且返回这个object。一旦这个属性被填充,再使用defaults方法将不会有任何效果。

说简单些,就是后面的对象补充前面的对象没有的字段。

// Fill in a given object with default properties.
  _.defaults = createAssigner(_.allKeys, true)
           

_.extend

将source对象中的所有属性简单地覆盖到destination对象上,并且返回 destination 对象. 复制是按顺序的, 所以后面的对象属性会把前面的对象属性覆盖掉(如果有重复)。

// Extend a given object with all the properties in passed-in object(s).
  _.extend = createAssigner(_.allKeys)
           

_.extendOwn

类似于 extend, 但只复制自己的属性覆盖到目标对象。(注:不包括继承过来的属性)。

// Assigns a given object with all the own properties in the passed-in object(s).
  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
  _.extendOwn = _.assign = createAssigner(_.keys)
           

createAssigner

// An internal function for creating assigner functions.
  var createAssigner = function(keysFunc, defaults) {
    return function(obj) {
      var length = arguments.length
      if (defaults) obj = Object(obj)
      // 如果参数小于2个或传进来的obj是空则直接返回obj
      if (length < 2 || obj == null) return obj
      for (var index = 1; index < length; index++) {
        var source = arguments[index],
          // 根据传进来的参数遍历方法获取参数
          keys = keysFunc(source),
          l = keys.length
        for (var i = 0; i < l; i++) {
          var key = keys[i]
          // 判断是否启用默认undefined不处理
          if (!defaults || obj[key] === void 0) obj[key] = source[key]
        }
      }
      return obj
    }
  }

           

这里有一个嵌套遍历,第一层是遍历参数,该API可以传入多个参数进行处理。第二层遍历具体参数中的属性并处理。

继续阅读