blob: b8f2802bb1f1426768169b5b19d7d00759fff906 [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001'use strict';
2
3var GetIntrinsic = require('get-intrinsic');
4
5var $TypeError = GetIntrinsic('%TypeError%');
6
7var callBound = require('call-bind/callBound');
8var forEach = require('../helpers/forEach');
9var OwnPropertyKeys = require('../helpers/OwnPropertyKeys');
10
11var $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');
12
13var CreateDataProperty = require('./CreateDataProperty');
14var Get = require('./Get');
15var IsArray = require('./IsArray');
16var IsInteger = require('./IsInteger');
17var IsPropertyKey = require('./IsPropertyKey');
18var SameValue = require('./SameValue');
19var ToNumber = require('./ToNumber');
20var ToObject = require('./ToObject');
21var Type = require('./Type');
22
23// https://262.ecma-international.org/9.0/#sec-copydataproperties
24
25module.exports = function CopyDataProperties(target, source, excludedItems) {
26 if (Type(target) !== 'Object') {
27 throw new $TypeError('Assertion failed: "target" must be an Object');
28 }
29
30 if (!IsArray(excludedItems)) {
31 throw new $TypeError('Assertion failed: "excludedItems" must be a List of Property Keys');
32 }
33 for (var i = 0; i < excludedItems.length; i += 1) {
34 if (!IsPropertyKey(excludedItems[i])) {
35 throw new $TypeError('Assertion failed: "excludedItems" must be a List of Property Keys');
36 }
37 }
38
39 if (typeof source === 'undefined' || source === null) {
40 return target;
41 }
42
43 var fromObj = ToObject(source);
44
45 var sourceKeys = OwnPropertyKeys(fromObj);
46 forEach(sourceKeys, function (nextKey) {
47 var excluded = false;
48
49 forEach(excludedItems, function (e) {
50 if (SameValue(e, nextKey) === true) {
51 excluded = true;
52 }
53 });
54
55 var enumerable = $isEnumerable(fromObj, nextKey) || (
56 // this is to handle string keys being non-enumerable in older engines
57 typeof source === 'string'
58 && nextKey >= 0
59 && IsInteger(ToNumber(nextKey))
60 );
61 if (excluded === false && enumerable) {
62 var propValue = Get(fromObj, nextKey);
63 CreateDataProperty(target, nextKey, propValue);
64 }
65 });
66
67 return target;
68};