Source: polyfill/Object.js

  1. // Licensed Materials - Property of IBM
  2. //
  3. // IBM Watson Analytics
  4. //
  5. // (C) Copyright IBM Corp. 2015, 2018
  6. //
  7. // US Government Users Restricted Rights - Use, duplication or
  8. // disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. ( function( exports, Object )
  10. {
  11. "use strict";
  12. /*global Symbol*/
  13. var hasOwnProperty = Object.prototype.hasOwnProperty;
  14. var toString = Object.prototype.toString;
  15. // RegExp set up to match BareJS and polyfill.io symbol strings
  16. // polyfill uses "__\x01symbol:" and "__\x01symbol@@"
  17. var reSymbol = /^__\d*\x01?[sS]ymbol/;
  18. // By default, make members whose name does not start with _ or $ enumerable.
  19. var reEnumerable = /^[^_\$]/;
  20. var strUndef = "undefined";
  21. var NativeSymbol = typeof Symbol !== strUndef ? Symbol : null;
  22. //jshint -W122
  23. var symIt = NativeSymbol && ( typeof Symbol.iterator === "symbol" ) ? Symbol.iterator : /*istanbul ignore next*/ null;
  24. //jshint +W122
  25. /**
  26. * Polyfills for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object Object}.
  27. * Module that provides implementations for methods missing on Object. Methods that cannot be polyfilled close enough to
  28. * the spec (since they rely on Native implementations) are not added to the Object global.
  29. * @class module:barejs/polyfill.Object
  30. */
  31. /** @lends module:barejs/polyfill.Object */
  32. var stat = {};
  33. /**
  34. * Shortcut method that only defines a property if it is not already known
  35. * @param {object} _target The object to polyfill
  36. * @param {object} _members The members to polyfill
  37. * @param {object} [_copy] Optional: an object that the definitions will be copied to.
  38. * @param {string} [_ownerName] Optional: name of the owner object
  39. * @memberof module:barejs/polyfill.Object~
  40. * @private
  41. */
  42. function polyMixin( _target, _members, _copy, _ownerName )
  43. {
  44. for ( var name in _members )
  45. {
  46. /*istanbul ignore else: we're working on clean objects, iterating prototype properties is unexpected*/
  47. if ( _members.hasOwnProperty( name ) )
  48. {
  49. var member = _members[name], isFn = typeof member === "function";
  50. if ( isFn && _ownerName )
  51. member.displayName = _ownerName + "." + name;
  52. if ( _copy )
  53. _copy[name] = member;
  54. if ( !( name in _target ) )
  55. exports.defineProperty( _target, name, { enumerable : false, configurable: isFn, writable: isFn, value: member } );
  56. }
  57. }
  58. }
  59. /**
  60. * Helper method that allows to easily apply static and prototype properties to a native object
  61. * @param {function} _native The native Object constructor to polyfill
  62. * @param {object} _static The static methods to polyfill. Can be null.
  63. * @param {object} _proto The instance members to polyfill. Can be null.
  64. * @param {object} [_copy] Optional: an object that the definitions will be copied to.
  65. * @param {string} [_ownerName] Optional: the name of the owner object.
  66. * Allows to add functions to "exports" as well, for unit testing.
  67. * @memberof module:barejs/polyfill.Object
  68. * @private
  69. */
  70. exports.polyfill = function polyfill( _native, _static, _proto, _copy, _ownerName )
  71. {
  72. if ( _static )
  73. polyMixin( _native, _static, _copy, _ownerName );
  74. if ( _proto )
  75. polyMixin( _native.prototype, _proto, _copy, _ownerName && ( _ownerName + ".prototype" ) );
  76. return _native;
  77. };
  78. exports.shouldBeEnumerable = function shouldBeEnumerable( _name )
  79. {
  80. return typeof _name === "string" && reEnumerable.test( _name );
  81. };
  82. /**
  83. * Utility method to check if _target is an Object
  84. * @param _arg The argument to check.
  85. * @returns {boolean} True if the target is an object, false otherwise
  86. */
  87. function isObject( _arg )
  88. {
  89. switch ( _arg && typeof _arg )
  90. {
  91. case "object":
  92. case "function":
  93. return true;
  94. default:
  95. return false;
  96. }
  97. }
  98. exports.isObject = isObject;
  99. /**
  100. * Utility method to convert target to an Object (according to Ecmascript standard)
  101. * @param _arg The argument to check.
  102. * @param _caller The function requesting the cast. If provided, changes the exception message.
  103. * @returns {object} The argument, as object
  104. * @throws {TypeError} A TypeError if _arg is null or undefined.
  105. */
  106. function toObject( _arg, _caller )
  107. {
  108. switch ( _arg === null ? strUndef : typeof _arg )
  109. {
  110. case "undefined":
  111. throw new TypeError( _caller ? _caller.displayName + " called on null or undefined" : "Cannot convert undefined or null to object" );
  112. case "object":
  113. case "function":
  114. return _arg;
  115. default:
  116. return Object( _arg );
  117. }
  118. }
  119. exports.toObject = toObject;
  120. /**
  121. * Check if _arg is callable (i.e. a function).
  122. * @param _arg The argument to check.
  123. * @returns {boolean} True if _arg is a function, false otherwise.
  124. * @memberof module:barejs/polyfill.Object
  125. * @private
  126. */
  127. exports.isCallable = function isCallable( _arg )
  128. {
  129. // We can't check the internal [[Call]] property, so we rely on type checking.
  130. return ( typeof _arg === "function" ) || ( toString.call( _arg ) === "[object Function]" );
  131. };
  132. /**
  133. * Convenience method to check if _arg is callable (i.e. a function).
  134. * Note: If a second argument is provided, that is returned instead of _arg.
  135. * This allows inlining the ensureCallable method in convenient locations.
  136. * @param _arg function to check
  137. * @returns _arg, or second argument if present
  138. * @throws {TypeError} if _arg is not callable.
  139. * @memberof module:barejs/polyfill.Object
  140. * @private
  141. */
  142. exports.ensureCallable = function ensureCallable( _arg )
  143. {
  144. if ( !exports.isCallable( _arg ) )
  145. throw new TypeError( _arg + " is not a function" );
  146. return arguments.length > 1 ? arguments[1] : _arg;
  147. };
  148. /**
  149. * Helper function that will attempt to set the ES6 iterator Symbol for a class.
  150. * @param {object} _target The object to define the iterator on.
  151. * @param {function} _function The function that will result in the iterator.
  152. * @returns {object} `_target`.
  153. * @memberof module:barejs/polyfill.Object
  154. * @private
  155. */
  156. function setIterator( _target, _function )
  157. {
  158. var def = { configurable: true, value: _function };
  159. /*istanbul ignore else: always true in NodeJS*/
  160. if ( symIt )
  161. exports.defineProperty( _target, symIt, def );
  162. // Set @@iterator for compliancy with polyfill libraries like core.js
  163. exports.defineProperty( _target, "@@iterator", def );
  164. return _target;
  165. }
  166. exports.setIterator = setIterator;
  167. /**
  168. * Helper function that will get the ES6 iterator Symbol for a class.
  169. * @param {function} _class The constructor function to define the iterator on
  170. * @returns {object} The iterator, or null.
  171. * @memberof module:barejs/polyfill.Object
  172. * @private
  173. */
  174. function getIterator( _target )
  175. {
  176. var result = null;
  177. if ( _target )
  178. {
  179. var obj = Object( _target );
  180. if ( symIt && ( symIt in obj ) )
  181. result = obj[symIt]();
  182. else if ( "@@iterator" in obj )
  183. result = obj["@@iterator"]();
  184. }
  185. return result;
  186. }
  187. exports.getIterator = getIterator;
  188. ////////////////////////////////////////////////////////////////////////////////////////////////////
  189. // Grab some methods that we may have to provide fallbacks for
  190. ////////////////////////////////////////////////////////////////////////////////////////////////////
  191. var modernPropertySupport = !!Object.defineProperties;
  192. var legacyPropertySupport = ( ( "__defineGetter__" in Object.prototype ) && ( "__defineSetter__" in Object.prototype ) );
  193. /*istanbul ignore next: We know we have Object.defineProperties in NodeJS*/
  194. exports.propertyGetSetSupport = modernPropertySupport || legacyPropertySupport;
  195. // Take care not to grab IE8's defineProperty that only works on DOM elements.
  196. /*istanbul ignore else: native in NodeJS*/
  197. if ( modernPropertySupport )
  198. {
  199. exports.defineProperty = Object.defineProperty;
  200. exports.defineProperties = Object.defineProperties;
  201. exports.getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
  202. exports.getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors;
  203. }
  204. exports.getPrototypeOf = Object.getPrototypeOf;
  205. exports.freeze = Object.freeze;
  206. exports.isFrozen = Object.isFrozen;
  207. exports.seal = Object.seal;
  208. exports.isSealed = Object.isSealed;
  209. // ES6
  210. exports.getOwnPropertyNames = Object.getOwnPropertyNames;
  211. exports.getOwnPropertySymbols = Object.getOwnPropertySymbols;
  212. /*istanbul ignore else: The tests are run with __ES__ set to 3*/
  213. if ( __ES__ < 5 )
  214. {
  215. ////////////////////////////////////////////////////////////////////////////////////////////////
  216. // ES5 fallback functions
  217. ////////////////////////////////////////////////////////////////////////////////////////////////
  218. // The following methods are not actually polyfills; these methods cannot be polyfilled.
  219. // However, if the fallback behavior provided by the methods is sufficient, these can be used.
  220. /*istanbul ignore if: native in NodeJS*/
  221. if ( !exports.defineProperty )
  222. {
  223. /*
  224. * Object.defineProperty cannot be emulated on browsers that do not support it.
  225. * However, if the intention is to just set a value (no getters/setters), and the loss of
  226. * enumerable, writable and configurable flags is acceptable, this method can be used.
  227. * Uses the native method where possible
  228. *
  229. * Note: check for compliance via Object.defineProperties, since IE8 has an Object.defineProperty,
  230. * but that only works on DOM elements.
  231. */
  232. exports.defineProperty = function defineProperty( _object, _name, _definition )
  233. {
  234. if ( !isObject( _object ) )
  235. throw new TypeError( "Object.defineProperty called on non-object" );
  236. /*
  237. * Fallback to simple assignment or __define[GS]etter__
  238. */
  239. // Only assign if it actually exists.
  240. if ( "value" in _definition )
  241. {
  242. _object[_name] = _definition.value;
  243. }
  244. else if ( ( "get" in _definition ) || ( "set" in _definition ) )
  245. {
  246. if ( !exports.propertyGetSetSupport )
  247. throw new Error( "Property getters and setters are not supported in this environment" );
  248. if ( "get" in _definition )
  249. _object.__defineGetter__( _name, _definition.get );
  250. if ( "set" in _definition )
  251. _object.__defineSetter__( _name, _definition.set );
  252. }
  253. return _object;
  254. };
  255. }
  256. /*istanbul ignore if: native in NodeJS*/
  257. if ( !exports.defineProperties )
  258. {
  259. /*
  260. * Uses the possibly emulated defineProperty and behaves like Object.defineProperties.
  261. * Can only be used to set values (no getters/setters) in environments that do not support getters/setters.
  262. * Uses the native method where possible
  263. */
  264. exports.defineProperties = function defineProperties( _object, _properties )
  265. {
  266. if ( !isObject( _object ) )
  267. throw new TypeError( "Object.defineProperties called on non-object" );
  268. _properties = toObject( _properties );
  269. // Assume there is no Object.keys in an environment that requires this polyfill.
  270. for ( var i in _properties )
  271. if ( hasOwnProperty.call( _properties, i ) && ( !reSymbol.test( i ) ) ) // Ignore Symbols
  272. exports.defineProperty( _object, i, _properties[i] );
  273. return _object;
  274. };
  275. }
  276. /*istanbul ignore if: native in NodeJS*/
  277. if ( !exports.getPrototypeOf )
  278. {
  279. /**
  280. * Object.getPrototypeOf cannot be fully emulated on browsers that do not support it.
  281. * We attempt to find a __proto__ or constructor.prototype.
  282. * Attempt to get an objects prototype, returns null on failure
  283. * @param {object} _object The object to get the prototype of
  284. * @returns {object} The prototype of _object
  285. * @memberof module:barejs/polyfill.Object
  286. * @private
  287. */
  288. exports.getPrototypeOf = function getPrototypeOf( _object )
  289. {
  290. switch ( _object === null ? strUndef : typeof _object )
  291. {
  292. case "undefined":
  293. throw new TypeError( "Cannot convert undefined or null to object" );
  294. case "boolean":
  295. return Boolean.prototype;
  296. case "number":
  297. return Number.prototype;
  298. case "string":
  299. return String.prototype;
  300. case "function":
  301. return Function.prototype;
  302. // case "object", and any other host value
  303. default:
  304. // jshint -W103
  305. if ( "__proto__" in _object )
  306. return _object.__proto__;
  307. // jshint +W103
  308. // If the object has the constructor property, this is already a prototype
  309. if ( !hasOwnProperty.call( _object, "constructor" ) )
  310. return _object.constructor.prototype;
  311. // See if a framework set a superclass property
  312. else if ( _object.constructor.superclass )
  313. return _object.constructor.superclass.prototype;
  314. if ( Array.isArray( _object ) )
  315. return Array.prototype;
  316. return null;
  317. }
  318. };
  319. }
  320. /*istanbul ignore if: native in NodeJS*/
  321. if ( !exports.freeze )
  322. {
  323. /*
  324. * Object.freeze cannot be emulated. This method is a NOOP if Object.freeze is not supported.
  325. */
  326. exports.freeze = function freeze( _o ){ return _o; };
  327. }
  328. /*istanbul ignore if: native in NodeJS*/
  329. if ( !exports.isFrozen )
  330. {
  331. /*
  332. * Object.isFrozen cannot be emulated. This method is a NOOP if Object.isFrozen is not supported.
  333. */
  334. exports.isFrozen = function isFrozen( _o ){ return false; };
  335. }
  336. /*istanbul ignore if: native in NodeJS*/
  337. if ( !exports.seal )
  338. {
  339. /*
  340. * Object.seal cannot be emulated. This method is a NOOP if Object.seal is not supported.
  341. */
  342. exports.seal = function seal( _o ){ return _o; };
  343. }
  344. /*istanbul ignore if: native in NodeJS*/
  345. if ( !exports.isSealed )
  346. {
  347. /*
  348. * Object.isSealed cannot be emulated. This method is a NOOP if Object.isSealed is not supported.
  349. */
  350. exports.isSealed = function isSealed( _o ){ return false; };
  351. }
  352. ////////////////////////////////////////////////////////////////////////////////////////////////
  353. // ES5 polyfills
  354. ////////////////////////////////////////////////////////////////////////////////////////////////
  355. //
  356. // ES5 - Object
  357. //
  358. ( function()
  359. {
  360. /*global document, ActiveXObject*/
  361. var createEmpty;
  362. // While we generally prefer named constructors, avoid it here since it adds no value,
  363. // and may even be confusing when looking at the prototype chain.
  364. var Anonymous = function(){};
  365. //jshint -W103
  366. /*istanbul ignore else: NodeJS supports the __proto__ property*/
  367. if ( ( !( { __proto__: null } instanceof Object ) ) || ( typeof document === strUndef ) )
  368. {
  369. // We can use the deprecated __proto__ property to create an object with no prototype
  370. createEmpty = function()
  371. {
  372. return { __proto__: null };
  373. };
  374. }
  375. //jshint +W103
  376. else
  377. {
  378. // We grab a foreign Object.prototype so any object created from it has instanceof Object return false,
  379. // and we can safely delete all properties from it without breaking regular objects.
  380. createEmpty = function()
  381. {
  382. var shouldUseActiveX = ( function()
  383. {
  384. try
  385. {
  386. return !!( document.domain && new ActiveXObject( "htmlfile" ) );
  387. }
  388. catch ( ex )
  389. {
  390. return false;
  391. }
  392. }() );
  393. function Empty() {}
  394. if ( shouldUseActiveX )
  395. {
  396. Empty.prototype = ( function( _xDoc )
  397. {
  398. _xDoc.write( "<script><\/script>" );
  399. _xDoc.close();
  400. var empty = _xDoc.parentWindow.Object.prototype;
  401. _xDoc = null;
  402. return empty;
  403. }( new ActiveXObject( "htmlfile" ) ));
  404. }
  405. else
  406. {
  407. Empty.prototype = ( function( _parent, _iframe )
  408. {
  409. _iframe.style.display = "none";
  410. _parent.appendChild( _iframe );
  411. // jshint -W107
  412. _iframe.src = "javascript:";
  413. // jshint +W107
  414. var empty = _iframe.contentWindow.Object.prototype;
  415. _parent.removeChild( _iframe );
  416. _iframe = null;
  417. return empty;
  418. }( document.body || document.documentElement, document.createElement( "iframe" ) ) );
  419. }
  420. // Now delete all existing definitions on our "empty" object to make it truly empty
  421. ( function( _e )
  422. {
  423. delete _e.constructor;
  424. delete _e.hasOwnProperty;
  425. delete _e.propertyIsEnumerable;
  426. delete _e.isPrototypeOf;
  427. delete _e.toLocaleString;
  428. delete _e.toString;
  429. delete _e.valueOf;
  430. }( Empty.prototype ) );
  431. // Shortcut createEmpty for future calls
  432. createEmpty = function()
  433. {
  434. // This returns an object for which instanceof Object is false
  435. return new Empty();
  436. };
  437. return createEmpty();
  438. };
  439. }
  440. /**
  441. * Create an instance of an object that has another object as its prototype
  442. * @param {object} _proto The prototype of the newly created object, or null.
  443. * @param {object} _properties
  444. * @returns {object} A new object that has the input object as prototype.
  445. */
  446. stat.create = function create( _proto, _properties )
  447. {
  448. var result;
  449. // _proto has 3 valid values: null or an Object (a function is an Object too)
  450. if ( _proto === null )
  451. {
  452. result = createEmpty();
  453. }
  454. else
  455. {
  456. if ( !isObject( _proto ) )
  457. throw new TypeError( "Object prototype may only be an Object or null: " + _proto );
  458. Anonymous.prototype = _proto;
  459. result = new Anonymous();
  460. Anonymous.prototype = null; // Reset prototype so we don't hold a reference to _proto
  461. }
  462. if ( typeof _properties !== strUndef )
  463. exports.defineProperties( result, toObject( _properties ) );
  464. return result;
  465. };
  466. }() );
  467. ( function()
  468. {
  469. var hasDontEnumBug = !( { toString: null } ).propertyIsEnumerable( "toString" ),
  470. dontEnums = [
  471. "toString",
  472. "toLocaleString",
  473. "valueOf",
  474. "hasOwnProperty",
  475. "isPrototypeOf",
  476. "propertyIsEnumerable",
  477. "constructor"
  478. ],
  479. dontEnumsLength = dontEnums.length;
  480. /**
  481. * Return the property names defined directly on object
  482. * @param {object} _obj The target object.
  483. * @returns {Array} String[] property names.
  484. */
  485. stat.keys = function keys( _obj )
  486. {
  487. // Ensure object
  488. _obj = toObject( _obj );
  489. var result = [];
  490. for ( var prop in _obj )
  491. if ( hasOwnProperty.call( _obj, prop ) && ( !reSymbol.test( prop ) ) ) // Ignore Symbols
  492. result.push(prop);
  493. /*istanbul ignore if: not applicable in NodeJS*/
  494. if ( hasDontEnumBug )
  495. {
  496. for ( var i = 0; i < dontEnumsLength; ++i )
  497. if ( hasOwnProperty.call( _obj, dontEnums[i] ) )
  498. result.push( dontEnums[i] );
  499. }
  500. return result;
  501. };
  502. }() );
  503. }
  504. /*istanbul ignore else: The tests are run with __ES__ set to 3*/
  505. if ( __ES__ < 6 )
  506. {
  507. // Technically most of the methods set on exports are in ES5, but BareJS relies on them so ensure there's a fallback
  508. /*istanbul ignore if: native in NodeJS*/
  509. if ( !exports.getOwnPropertyNames )
  510. {
  511. exports.getOwnPropertyNames = function( _object )
  512. {
  513. var result = [];
  514. if ( _object )
  515. {
  516. var obj = Object( _object );
  517. for ( var key in obj )
  518. {
  519. if ( hasOwnProperty.call( obj, key ) && typeof key === "string" )
  520. result.push( key );
  521. }
  522. }
  523. return result;
  524. };
  525. }
  526. /*istanbul ignore if: native in NodeJS*/
  527. if ( !exports.getOwnPropertySymbols )
  528. {
  529. exports.getOwnPropertySymbols = function getOwnPropertySymbols( _target )
  530. {
  531. // Ensure object
  532. _target = toObject( _target );
  533. var result = [];
  534. for ( var prop in _target )
  535. if ( hasOwnProperty.call( _target, prop ) && ( reSymbol.test( prop ) ) )
  536. result.push(prop);
  537. return result;
  538. };
  539. }
  540. /*istanbul ignore if: native in NodeJS*/
  541. if ( !exports.getOwnPropertyDescriptor )
  542. {
  543. exports.getOwnPropertyDescriptor = function getOwnPropertyDescriptor( _object, _key )
  544. {
  545. var descriptor;
  546. if ( _object )
  547. {
  548. var obj = Object( _object );
  549. if ( hasOwnProperty.call( obj, _key ) )
  550. {
  551. descriptor = { configurable: true, enumerable: true };
  552. var getter;
  553. var setter;
  554. if ( legacyPropertySupport )
  555. {
  556. getter = obj.__lookupGetter__( _key );
  557. setter = obj.__lookupSetter__( _key );
  558. }
  559. if ( getter || setter )
  560. {
  561. if ( getter )
  562. descriptor.get = getter;
  563. if ( setter )
  564. descriptor.set = setter;
  565. }
  566. else
  567. {
  568. descriptor.value = obj[_key];
  569. }
  570. }
  571. }
  572. return descriptor;
  573. };
  574. }
  575. /*istanbul ignore if: native in NodeJS*/
  576. if ( !exports.getOwnPropertyDescriptors )
  577. {
  578. exports.getOwnPropertyDescriptors = function( _object )
  579. {
  580. var descriptors = {};
  581. if ( _object )
  582. {
  583. var names = exports.getOwnPropertyNames( _object );
  584. for ( var i = 0, len = names.length; i < len; ++i )
  585. descriptors[names[i]] = exports.getOwnPropertyDescriptor( _object, names[i] );
  586. }
  587. return descriptors;
  588. };
  589. }
  590. /**
  591. * Object.is() determines whether two values are the same value. Two values are the same if one of the following holds:
  592. * - both undefined
  593. * - both null
  594. * - both true or both false
  595. * - both strings of the same length with the same characters
  596. * - both the same object
  597. * - both numbers and
  598. * - both +0
  599. * - both -0
  600. * - both NaN
  601. * - or both non-zero and both not NaN and both have the same value
  602. * @param _v1 The first value to compare.
  603. * @param _v2 The second value to compare.
  604. * @returns {boolean} A new object that has the input object as prototype.
  605. */
  606. stat.is = function is( _v1, _v2 )
  607. {
  608. if ( _v1 === _v2 )
  609. return ( _v1 !== 0 ) || ( 1 / _v1 === 1 / _v2 ); // Ensure Object.is( +0, -0 ) returns false
  610. else
  611. return ( _v1 !== _v1 ) && ( _v2 !== _v2 ); // Ensure Object.is( NaN, NaN ) returns true
  612. };
  613. /**
  614. * The Object.assign() method only copies enumerable and own properties from a source object to a target object.
  615. * It uses [[Get]] on the source and [[Put]] on the target, so it will invoke getters and setters.
  616. * Therefore it assigns properties versus just copying or defining new properties.
  617. * This may make it unsuitable for merging new properties into a prototype if the merge sources contain getters.
  618. * For copying property definitions, including their enumerability, into prototypes Object.getOwnPropertyDescriptor() and Object.defineProperty() should be used instead.
  619. * @param {object} _target The target to assign to.
  620. * @param {object} _firstSource The first source object to copy from.
  621. * @returns {object} the _target, with properties assigned.
  622. */
  623. stat.assign = function assign( _target, _firstSource /*assign.length should be 2*/ )
  624. {
  625. // Ensure object
  626. _target = toObject( _target );
  627. for ( var arg = 1, argLen = arguments.length, source; arg < argLen; ++arg )
  628. {
  629. if ( isObject( source = arguments[arg] ) )
  630. {
  631. for ( var key in source )
  632. {
  633. /*istanbul ignore else: clean prototypes assumed*/
  634. if ( hasOwnProperty.call( source, key ) )
  635. _target[key] = source[key];
  636. }
  637. }
  638. }
  639. return _target;
  640. };
  641. // End of ES6 polyfill scope
  642. }
  643. if ( __ES__ < 7 )
  644. {
  645. /**
  646. * The Object.values() method returns an array of a given object's own enumerable property values,
  647. * in the same order as that provided by a for...in loop
  648. * (the difference being that a for-in loop enumerates properties in the prototype chain as well).
  649. * @param {object} _target The object to enumerate.
  650. * @returns {Array} The array of values
  651. */
  652. stat.values = function values( _target )
  653. {
  654. // Avoid using Array.map for speed (and perform in-place replacement)
  655. for ( var t = toObject( _target ), result = Object.keys( t ), i = 0, len = result.length; i < len; ++i )
  656. result[i] = t[result[i]];
  657. return result;
  658. };
  659. /**
  660. * The Object.entries() method returns an array of a given object's own enumerable property [key, value] pairs,
  661. * in the same order as that provided by a for...in loop
  662. * (the difference being that a for-in loop enumerates properties in the prototype chain as well).
  663. * @param {object} _target The object to enumerate.
  664. * @returns {Array} The array of values
  665. */
  666. stat.entries = function entries( _target )
  667. {
  668. // Avoid using Array.map for speed (and perform in-place replacement)
  669. for ( var t = toObject( _target ), result = Object.keys( t ), i = 0, len = result.length; i < len; ++i )
  670. result[i] = [ result[i], t[result[i]] ];
  671. return result;
  672. };
  673. // End of ES7 polyfill scope
  674. }
  675. // Apply static members (not using exports.polyfill since we only have static members)
  676. polyMixin( Object, stat, exports, "Object" );
  677. //
  678. // ES6 - ES5 Patching
  679. //
  680. /*istanbul ignore else: The tests are run with __ES__ set to 3*/
  681. if ( __ES__ < 6 )
  682. {
  683. // It is possible Object.create exists (natively or polyfilled), but does not support the second
  684. // argument. In this case, we replace it with a method that will call defineProperties
  685. // We define this in the ES6 scope since we assume ES7 browsers will all support the optional second argument.
  686. /*istanbul ignore if: NodeJS's Object.create supports the second argument*/
  687. if ( Object.create( null, { test: { value: true } } ).test !== true )
  688. {
  689. Object.create = ( function( _originalCreate )
  690. {
  691. /**
  692. * Object.create wrapper that adds support for an optional second argument.
  693. */
  694. return function create( _proto, _properties )
  695. {
  696. var result = _originalCreate.call( Object, _proto ); // Call native Object.create
  697. if ( _properties )
  698. exports.defineProperties( result, _properties );
  699. return result;
  700. };
  701. }( Object.create ) );
  702. }
  703. }
  704. // End of module
  705. }( exports, Object ) );