1// Copyright JS Foundation and other contributors, http://js.foundation 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15var object1 = { 16 a: 1, 17 b: 2, 18 c: 3 19}; 20 21var object2 = Object.assign ({c: 4, d: 5}, object1); 22 23assert (JSON.stringify (object2) === '{"c":3,"d":5,"a":1,"b":2}'); 24assert (object2.c === 3); 25assert (object2.d === 5); 26 27// Cloning an object 28var obj = { a: 1 }; 29var copy = Object.assign ({}, obj); 30assert (JSON.stringify (copy) === '{"a":1}'); // { a: 1 } 31 32// Warning for Deep Clone 33function deepClone() { 34 'use strict'; 35 36 var obj1 = { a: 0 , b: { c: 0}}; 37 var obj2 = Object.assign ({}, obj1); 38 assert (JSON.stringify (obj2) === '{"a":0,"b":{"c":0}}'); 39 40 obj1.a = 1; 41 assert (JSON.stringify (obj1) === '{"a":1,"b":{"c":0}}'); 42 assert (JSON.stringify (obj2) === '{"a":0,"b":{"c":0}}'); 43 44 obj2.a = 2; 45 assert (JSON.stringify (obj1) === '{"a":1,"b":{"c":0}}'); 46 assert (JSON.stringify (obj2) === '{"a":2,"b":{"c":0}}'); 47 48 obj2.b.c = 3; 49 assert (JSON.stringify (obj1) === '{"a":1,"b":{"c":3}}'); 50 assert (JSON.stringify (obj2) === '{"a":2,"b":{"c":3}}'); 51 52 // Deep Clone 53 obj1 = { a: 0 , b: { c: 0}}; 54 var obj3 = JSON.parse (JSON.stringify (obj1)); 55 obj1.a = 4; 56 obj1.b.c = 4; 57 assert (JSON.stringify (obj3) === '{"a":0,"b":{"c":0}}'); 58} 59 60deepClone(); 61 62// Merging objects 63var o1 = { a: 1 }; 64var o2 = { b: 2 }; 65var o3 = { c: 3 }; 66 67var obj = Object.assign (o1, o2, o3); 68assert (JSON.stringify (obj) === '{"a":1,"b":2,"c":3}'); 69assert (JSON.stringify (o1) === '{"a":1,"b":2,"c":3}'); //target object itself is changed. 70 71//Merging objects with same properties 72var o1 = { a: 1, b: 1, c: 1 }; 73var o2 = { b: 2, c: 2 }; 74var o3 = { c: 3 }; 75 76var obj = Object.assign ({}, o1, o2, o3); 77assert (JSON.stringify (obj) === '{"a":1,"b":2,"c":3}'); 78 79// Properties on the prototype chain and non-enumerable properties cannot be copied 80var obj = Object.create({ foo: 1 }, { // foo is on obj's prototype chain. 81 bar: { 82 value: 2 // bar is a non-enumerable property. 83 }, 84 baz: { 85 value: 3, 86 enumerable: true // baz is an own enumerable property. 87 } 88}); 89 90var copy = Object.assign ({}, obj); 91assert (JSON.stringify (copy) === '{"baz":3}'); 92 93// Primitives will be wrapped to objects 94var v1 = 'abc'; 95var v2 = true; 96var v3 = 10; 97 98var obj = Object.assign ({}, v1, null, v2, undefined, v3); 99// Primitives will be wrapped, null and undefined will be ignored. 100// Note, only string wrappers can have own enumerable properties. 101assert (JSON.stringify (obj) === '{"0":"a","1":"b","2":"c"}'); 102 103//Exceptions will interrupt the ongoing copying task 104var target = Object.defineProperty ({}, 'foo', { 105 value: 1, 106 writable: false 107}); // target.foo is a read-only property 108 109try { 110 // TypeError: "foo" is read-only,the Exception is thrown when assigning target.foo 111 Object.assign (target, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 }); 112 assert (false); 113} catch (e) { 114 assert (e instanceof TypeError); 115} 116 117assert (target.bar === 2); // the first source was copied successfully. 118assert (target.foo2 === 3); // the first property of the second source was copied successfully. 119assert (target.foo === 1); // exception is thrown here. 120assert (target.foo3 === undefined); // assign method has finished, foo3 will not be copied. 121assert (target.baz === undefined); // the third source will not be copied either. 122 123// Copying accessors 124var obj = { 125 foo: 1, 126 get bar() { 127 return 2; 128 } 129}; 130 131var copy = Object.assign ({}, obj); 132assert (JSON.stringify (copy) === '{"foo":1,"bar":2}'); 133assert (copy.bar === 2); // the value of copy.bar is obj.bar's getter's return value. 134 135// This is an assign function that copies full descriptors 136function completeAssign (target, sources) { 137 sources.forEach (source => { 138 var descriptors = Object.keys (source).reduce ((descriptors, key) => { 139 descriptors[key] = Object.getOwnPropertyDescriptor (source, key); 140 return descriptors; 141 }, {}); 142 143 Object.defineProperties (target, descriptors); 144 }); 145 return target; 146} 147 148var copy = completeAssign ({}, [obj]); 149assert (JSON.stringify (copy) === '{"foo":1,"bar":2}'); 150assert (copy.bar === 2); 151 152// Test when target is not coercible to object 153try { 154 Object.assign.call (undefined); 155 assert (false); 156} catch (e) { 157 assert (e instanceof TypeError) 158} 159 160var asd = Symbol ("asd"); 161var foo = Symbol ("foo"); 162var bar = Symbol ("bar"); 163var obj = {1: 5, "a": 6, [foo]: 7, [asd]: 8, [bar]: 9}; 164var result = Object.assign ({}, obj); 165assert (result[foo] == 7); 166assert (result[asd] == 8); 167assert (result[bar] == 9); 168