Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of `Object(target)` in the `Object.assign()` polyfill

In the MDN page forObject.assign() the example polyfill first wraps all sources and the target parameters in Object() before iterating over the properties. (i.e. Object(target), Object(source1), Object(source2)...).

The text also mentions that the additional properties are added directly to the target before returning the target. However, wrapping the target in Object() results in an object that is different than simply augmenting properties. (i.e. Object(target).newProp !== target.newProp).

All the examples given have objects as parameters to Object.assign(). The use-case for non-object source or target parameters is therefore not clear.

A) What is the purpose of wrapping parameters in Object()? (I am under the impression that Object.keys(x) is the same as Object.keys(Object(x))).

B) What are possible use cases for using Object.assign() with non-objects, is any? (for example something like: Object.assign(1, 'b', [3], true, function(){}) )

like image 483
Hurelu Avatar asked Feb 22 '15 11:02

Hurelu


People also ask

What is object assign used for?

Object.assign() The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.

How do you assign a value to an object?

assign() which is used to copy the values and properties from one or more source objects to a target object. It invokes getters and setters since it uses both [[Get]] on the source and [[Set]] on the target. It returns the target object which has properties and values copied from the target object.

How do you assign one object to another in JavaScript?

var clone = Object. assign({}, obj); The Object. assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object.

How do you assign values from one object to another in TypeScript?

To use the Object. assign() method in TypeScript, pass a target object as the first parameter to the method and one or more source objects, e.g. const result = Object. assign({}, obj1, obj2) . The method will copy the properties from the source objects to the target object.


1 Answers

Let's break it down:

Test if the object exists, if not make it:

if (!Object.assign) {

Make the method via Object.defineProperty and add it to Object

    Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,

Here the actual function gets set. One needs to supply a target and one source minimum.

    value: function(target, firstSource) {
      'use strict';

If the target is not defined throw an error.

      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }

Cast the target to Object format. (E.g. String 1234 to [object String]{0: "1", 1: "2", 2: "3", 3: "4", length: 4}.

      var to = Object(target);

Now loop through all sources using the arguments object of the function. Start with 1, since 0 is the target.

      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i]; //store the argument in a variable.
        if (nextSource === undefined || nextSource === null) {
          continue; //if the source is undefined continue. 
        }

Then we need all (not only the exposed) the enumerable properties from the source object, use Object.keys in combination with Object(source).

        var keysArray = Object.keys(Object(nextSource));

Iterate over the keys:

        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex]; //select the key from the index.

getOwnPropertyDescriptor gives us information about the property in the form of an object.

          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);

If the property is not undefined and is enumerable then set this property as a property to to.

          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}

Finally return to with the newly added (cloned) properties.

like image 140
Mouser Avatar answered Nov 14 '22 23:11

Mouser