Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save WebReflection/9317065 to your computer and use it in GitHub Desktop.
Save WebReflection/9317065 to your computer and use it in GitHub Desktop.
A plural ES5 + ES6 friendly version of Object.getOwnPropertyDescriptor
'getOwnPropertyDescriptors' in Object || (
Object.getOwnPropertyDescriptors = function (Object) {
var
gOPD = Object.getOwnPropertyDescriptor,
gOPN = Object.getOwnPropertyNames,
gOPS = Object.getOwnPropertySymbols,
gNS = gOPS ? function (object) {
return gOPN(object).concat(gOPS(object));
} :
gOPN,
descriptors
;
function copyFrom(key) {
descriptors[key] = gOPD(this, key);
}
return function getOwnPropertyDescriptors(object) {
var result = descriptors = {};
gNS(object).forEach(copyFrom, object);
descriptors = null;
return result;
};
}(Object)
);
@WebReflection
Copy link
Author

the aim of this proposal is to make possible to create a shallow copy of a generic JS object in this way

var shallowCopy = Object.create(
  Object.getPrototypeOf(originalObject),
  Object.getOwnPropertyDescriptors(originalObject)
);

another pattern solved by this proposal is the following:

Object.defineProperties(
  target,
  Object.getOwnPropertyDescriptors(source)
);

which is useful to simulate Object.mixin which didn't make it in ES6, together with previously mentioned Object.clone or copy as shallow.

@WebReflection
Copy link
Author

this has been written also as ES6 specification

Looking forward for the next TC39 meeting in April

@ljharb
Copy link

ljharb commented Jan 30, 2015

An alternate polyfillable ES6 version that relies on Reflect.ownKeys, Array#reduce, and Object.getOwnPropertyDescriptor:

function getOwnPropertyDescriptors(obj) {
  return Reflect.ownKeys(obj).reduce(function (acc, key) {
    acc[key] = Object.getOwnPropertyDescriptor(obj, key);
    return acc;
  }, {});
}

(just posting this comment here so I don't forget it later ;-) )

@WebReflection
Copy link
Author

A possible Object.copy that works like Object.assign but includes getters, setters, and non enumerable properties too.

Object.copy = (function (O) {
  var
    dP    = O.defineProperty,
    gOPD  = O.getOwnPropertyDescriptor,
    gOPN  = O.getOwnPropertyNames,
    gOPS  = O.getOwnPropertySymbols,
    set   = function (target, source) {
      for (var
        key,
        keys = gOPN(source).concat(gOPS(source)),
        i = 0,
        l = keys.length; i < l; i++
      ) {
        key = keys[i];
        dP(target, key, gOPD(source, key));
      }
    }
  ;
  return function copy(target) {
    for (var i = 1, l = arguments.length; i < l; i++) {
      set(target, arguments[i]);
    }
    return target;
  };
}(Object));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment