Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object.assign vs $.extend ? #32

Open
shiiiiiiji opened this issue Jun 28, 2018 · 0 comments
Open

Object.assign vs $.extend ? #32

shiiiiiiji opened this issue Jun 28, 2018 · 0 comments

Comments

@shiiiiiiji
Copy link
Owner

shiiiiiiji commented Jun 28, 2018

在业务工作中,如果你需要封装一个组件,你肯定会遇到这样的场景:组件的默认的配置对象defaultOption,需要与暴露出去的api进行合并,保证用户自定义的值能覆盖默认配置,但未定义的值取默认配置。其实,这本质上就是需要把defaultOption对象与外部传入的配置对象进行合并。我们经常会看到两种写法:Object.assign$.extend,那这两者有没有区别呢?

Object.assign()和$.extend()用法

首先呈现官方文档:Object.assign()jQuery.extend()

  • Object.assign()
    Object.assign(target, ...sources),Returns: Object

  • $.extend()
    jQuery.extend( target [, object1 ] [, objectN ] ), Returns: Object
    jQuery.extend( [deep ], target, object1 [, objectN ] ), If true, the merge becomes recursive(递归) (aka. deep copy,深拷贝).

The Object.assign() method only copies enumerable and own properties from a source object to a target object.

$.extends(): Merge the contents of two or more objects together into the first object.

区别

两者区别其实不大:

  • 主要在于$.extend()如果给第一个参数传入true可实现deep merge,而Object.assign只会copies that reference value
  • 另外,就是使用$.extend()需要提前引入jQuery

Talk is Cheap, show me the code

  • 如果不想改变target object,可以将第一个参数传入空对象{}
var opts = Object.assign( {}, defaults, options );
// 或者
var opts = $.extend( {}, defaults, options );
  • Polyfill of Object.extend()
if (typeof Object.assign != 'function') {
  // Must be writable: true, enumerable: false, configurable: true
  Object.defineProperty(Object, "assign", {
    value: function assign(target, varArgs) { // .length of function is 2
      'use strict';
      if (target == null) { // TypeError if undefined or null
        throw new TypeError('Cannot convert undefined or null to object');
      }

      var to = Object(target);

      for (var index = 1; index < arguments.length; index++) {
        var nextSource = arguments[index];

        if (nextSource != null) { // Skip over if undefined or null
          for (var nextKey in nextSource) {
            // Avoid bugs when hasOwnProperty is shadowed
            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
              to[nextKey] = nextSource[nextKey];
            }
          }
        }
      }
      return to;
    },
    writable: true,
    configurable: true
  });
}
  • 如何使用Object.assign()实现deep merge
function isObject(item) {
  return (item && typeof item === 'object' && !Array.isArray(item));
}

function mergeDeep(target, ...sources) {
  if (!sources.length) return target;
  const source = sources.shift();

  if (isObject(target) && isObject(source)) {
    for (const key in source) {
      if (isObject(source[key])) {
        if (!target[key]) Object.assign(target, { [key]: {} });
        mergeDeep(target[key], source[key]);
      } else {
        Object.assign(target, { [key]: source[key] });
      }
    }
  }
  return mergeDeep(target, ...sources);
}

参考资料

(本篇完)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant