Gary Sieling

Why lodash “extend” or “assignTo” can skip properties

If you look at the prototype for an object in the browser console, you will see some proprties rendered in a light purple:

If you run “_.extend” on an object that has these, they will also disappear, like so:

However, you definitely can reference them directly (this one gives me an error, but obviously it’s actually there):

In the lodash source, “extend” is also known as assignIn:

  var assignIn = createAssigner(function(object, source) {
    copyObject(source, keysIn(source), object);
  });

You can call _.keysIn directly, and see that the interesting properties are not returned:

_.keysIn(React.Component.prototype)
["isReactComponent", "setState", "forceUpdate"]

Suprisingly, “hasOwnProperty” returns true for one of the ‘missing’ functions:

React.Component.prototype.hasOwnProperty("isMounted")
true

However, lodash will detect that an object is a prototype object by looking for a constructor:

 var Ctor = object.constructor,
          index = -1,
          isProto = typeof Ctor == 'function' && Ctor.prototype === object,
          result = Array(length),
          skipIndexes = length > 0;

If it is a prototype object, it then skips the constructor automatically.

The other missing properties are of a special class, called non-enumerable properties.

Armed with this knowledge, you can look into the React source, and find they use this all over the place, which explains the root problem:

Object.defineProperty(element._store, 'validated', {
  configurable: false,
  enumerable: false,
  writable: true,
  value: false
});
Exit mobile version