Object.setPrototypeOf()

The object.setProtoTypeof () method sets the Prototype of a specified Object (that is, the internal [[Prototype]] property) to another Object or null.

var dict = Object.setPrototypeOf({}, null);
Copy the code
if (!Object.setPrototypeOf) {
    // Only works with Chrome and FireFox, does not work in IE:
     Object.prototype.setPrototypeOf = function(obj, proto) {
         if(obj.__proto__) {
             obj.__proto__ = proto;
             return obj;
         } else {
             // If you want to return prototype of Object.create(null):
             var Fn = function() {
                 for (var key in obj) {
                     Object.defineProperty(this, key, {
                         value: obj[key], }); }}; Fn.prototype = proto;return newFn(); }}}Copy the code

Additional prototype chain

The combination of object.getProtoTypeof () and object.prototype.__proto__ allows an entire prototype chain to be attached to a new prototype Object:

/**
*** Object.appendChain(@object.@prototype)
*
* Appends the first non-native prototype of a chain to a new prototype.
* Returns @object (if it was a primitive value it will transformed into an object).
*
*** Object.appendChain(@object [."@arg_name_1", "@arg_name_2", "@arg_name_3", "..." ] ,"@function_body")
*** Object.appendChain(@object [."@arg_name_1, @arg_name_2, @arg_name_3, ..." ] ,"@function_body")
*
* Appends the first non-native prototype of a chain to the native Function.prototype object, then appends a
* new Function(["@arg"(s)], "@function_body") to that chain.
* Returns the function.
*
**/

Object.appendChain = function(oChain, oProto) {
  if (arguments.length < 2) {
    throw new TypeError('Object.appendChain - Not enough arguments');
  }
  if (typeof oProto === 'number' || typeof oProto === 'boolean') {
    throw new TypeError('second argument to Object.appendChain must be an object or a string');
  }

  var oNewProto = oProto,
      oReturn,
      o2nd,
      oLast;

  oReturn = o2nd = oLast = oChain instanceof this ? oChain : new oChain.constructor(oChain);

  for (var o1st = this.getPrototypeOf(o2nd); o1st ! = =Object.prototype && o1st ! = =Function.prototype;
    o1st = this.getPrototypeOf(o2nd)
  ) {
    o2nd = o1st;
  }

  if (oProto.constructor === String) {
    oNewProto = Function.prototype;
    oReturn = Function.apply(null.Array.prototype.slice.call(arguments.1));
    this.setPrototypeOf(oReturn, oLast);
  }

  this.setPrototypeOf(o2nd, oNewProto);
  return oReturn;
}
Copy the code

use

Example 1: Attach a chain to a prototype

function Mammal() {
  this.isMammal = 'yes';
}

function MammalSpecies(sMammalSpecies) {
  this.species = sMammalSpecies;
}

MammalSpecies.prototype = new Mammal();
MammalSpecies.prototype.constructor = MammalSpecies;

var oCat = new MammalSpecies('Felis');

console.log(oCat.isMammal);
// 'yes'

function Animal() {
  this.breathing = 'yes';
}

Object.appendChain(oCat, new Animal());

console.log(oCat.breathing);
// 'yes'
Copy the code

Example 2: Convert a primitive type to the corresponding object type and add it to the stereotype chain

function Symbol() {
  this.isSymbol = 'yes';
}

var nPrime = 17;

console.log(typeof nPrime); // 'number'

var oPrime = Object.appendChain(nPrime, new Symbol());

console.log(oPrime); / / '17'
console.log(oPrime.isSymbol); // 'yes'
console.log(typeof oPrime); // 'object'
Copy the code

Copy to Clipboard

Example 3: Add a chain to an object of function type and add a new method to that chain

function Person(sName) {
  this.identity = sName;
}

var george = Object.appendChain(new Person('George'), 'console.log("Hello guys!!" ); ');

console.log(george.identity); // 'George'
george(); // 'Hello guys!! '
Copy the code

Object.assign()

The object.assign () method is used to assign the values of all enumerable properties from one or more source objects to target objects. It will return the target object.

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 || target === undefined) {
        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&& nextSource ! = =undefined) {
          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
  });
}
Copy the code

Deep copy problem

For deep copies, an alternative approach is needed because object.assign () copies (enumerable) property values.

If the source value is a reference to an object, it simply copies its reference value.

Merge objects with the same properties

const o1 = { a: 1, b: 1, c: 1 };
const o2 = { b: 2, c: 2 };
const o3 = { c: 3 };

const obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
Copy the code

Execute function immediately

    var Browser = (function () {
        function Browser() {
            this.firefox = false;
            this.ie = false;
            this.edge = false;
            this.newEdge = false;
            this.weChat = false;
        }
        returnBrowser; } ());this.browser = new Browser();
Copy the code