1425bb815Sopenharmony_ci// Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci// 3425bb815Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci// you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci// You may obtain a copy of the License at 6425bb815Sopenharmony_ci// 7425bb815Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci// 9425bb815Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci// See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci// limitations under the License. 14425bb815Sopenharmony_ci 15425bb815Sopenharmony_civar object1 = { 16425bb815Sopenharmony_ci a: 1, 17425bb815Sopenharmony_ci b: 2, 18425bb815Sopenharmony_ci c: 3 19425bb815Sopenharmony_ci}; 20425bb815Sopenharmony_ci 21425bb815Sopenharmony_civar object2 = Object.assign ({c: 4, d: 5}, object1); 22425bb815Sopenharmony_ci 23425bb815Sopenharmony_ciassert (JSON.stringify (object2) === '{"c":3,"d":5,"a":1,"b":2}'); 24425bb815Sopenharmony_ciassert (object2.c === 3); 25425bb815Sopenharmony_ciassert (object2.d === 5); 26425bb815Sopenharmony_ci 27425bb815Sopenharmony_ci// Cloning an object 28425bb815Sopenharmony_civar obj = { a: 1 }; 29425bb815Sopenharmony_civar copy = Object.assign ({}, obj); 30425bb815Sopenharmony_ciassert (JSON.stringify (copy) === '{"a":1}'); // { a: 1 } 31425bb815Sopenharmony_ci 32425bb815Sopenharmony_ci// Warning for Deep Clone 33425bb815Sopenharmony_cifunction deepClone() { 34425bb815Sopenharmony_ci 'use strict'; 35425bb815Sopenharmony_ci 36425bb815Sopenharmony_ci var obj1 = { a: 0 , b: { c: 0}}; 37425bb815Sopenharmony_ci var obj2 = Object.assign ({}, obj1); 38425bb815Sopenharmony_ci assert (JSON.stringify (obj2) === '{"a":0,"b":{"c":0}}'); 39425bb815Sopenharmony_ci 40425bb815Sopenharmony_ci obj1.a = 1; 41425bb815Sopenharmony_ci assert (JSON.stringify (obj1) === '{"a":1,"b":{"c":0}}'); 42425bb815Sopenharmony_ci assert (JSON.stringify (obj2) === '{"a":0,"b":{"c":0}}'); 43425bb815Sopenharmony_ci 44425bb815Sopenharmony_ci obj2.a = 2; 45425bb815Sopenharmony_ci assert (JSON.stringify (obj1) === '{"a":1,"b":{"c":0}}'); 46425bb815Sopenharmony_ci assert (JSON.stringify (obj2) === '{"a":2,"b":{"c":0}}'); 47425bb815Sopenharmony_ci 48425bb815Sopenharmony_ci obj2.b.c = 3; 49425bb815Sopenharmony_ci assert (JSON.stringify (obj1) === '{"a":1,"b":{"c":3}}'); 50425bb815Sopenharmony_ci assert (JSON.stringify (obj2) === '{"a":2,"b":{"c":3}}'); 51425bb815Sopenharmony_ci 52425bb815Sopenharmony_ci // Deep Clone 53425bb815Sopenharmony_ci obj1 = { a: 0 , b: { c: 0}}; 54425bb815Sopenharmony_ci var obj3 = JSON.parse (JSON.stringify (obj1)); 55425bb815Sopenharmony_ci obj1.a = 4; 56425bb815Sopenharmony_ci obj1.b.c = 4; 57425bb815Sopenharmony_ci assert (JSON.stringify (obj3) === '{"a":0,"b":{"c":0}}'); 58425bb815Sopenharmony_ci} 59425bb815Sopenharmony_ci 60425bb815Sopenharmony_cideepClone(); 61425bb815Sopenharmony_ci 62425bb815Sopenharmony_ci// Merging objects 63425bb815Sopenharmony_civar o1 = { a: 1 }; 64425bb815Sopenharmony_civar o2 = { b: 2 }; 65425bb815Sopenharmony_civar o3 = { c: 3 }; 66425bb815Sopenharmony_ci 67425bb815Sopenharmony_civar obj = Object.assign (o1, o2, o3); 68425bb815Sopenharmony_ciassert (JSON.stringify (obj) === '{"a":1,"b":2,"c":3}'); 69425bb815Sopenharmony_ciassert (JSON.stringify (o1) === '{"a":1,"b":2,"c":3}'); //target object itself is changed. 70425bb815Sopenharmony_ci 71425bb815Sopenharmony_ci//Merging objects with same properties 72425bb815Sopenharmony_civar o1 = { a: 1, b: 1, c: 1 }; 73425bb815Sopenharmony_civar o2 = { b: 2, c: 2 }; 74425bb815Sopenharmony_civar o3 = { c: 3 }; 75425bb815Sopenharmony_ci 76425bb815Sopenharmony_civar obj = Object.assign ({}, o1, o2, o3); 77425bb815Sopenharmony_ciassert (JSON.stringify (obj) === '{"a":1,"b":2,"c":3}'); 78425bb815Sopenharmony_ci 79425bb815Sopenharmony_ci// Properties on the prototype chain and non-enumerable properties cannot be copied 80425bb815Sopenharmony_civar obj = Object.create({ foo: 1 }, { // foo is on obj's prototype chain. 81425bb815Sopenharmony_ci bar: { 82425bb815Sopenharmony_ci value: 2 // bar is a non-enumerable property. 83425bb815Sopenharmony_ci }, 84425bb815Sopenharmony_ci baz: { 85425bb815Sopenharmony_ci value: 3, 86425bb815Sopenharmony_ci enumerable: true // baz is an own enumerable property. 87425bb815Sopenharmony_ci } 88425bb815Sopenharmony_ci}); 89425bb815Sopenharmony_ci 90425bb815Sopenharmony_civar copy = Object.assign ({}, obj); 91425bb815Sopenharmony_ciassert (JSON.stringify (copy) === '{"baz":3}'); 92425bb815Sopenharmony_ci 93425bb815Sopenharmony_ci// Primitives will be wrapped to objects 94425bb815Sopenharmony_civar v1 = 'abc'; 95425bb815Sopenharmony_civar v2 = true; 96425bb815Sopenharmony_civar v3 = 10; 97425bb815Sopenharmony_ci 98425bb815Sopenharmony_civar obj = Object.assign ({}, v1, null, v2, undefined, v3); 99425bb815Sopenharmony_ci// Primitives will be wrapped, null and undefined will be ignored. 100425bb815Sopenharmony_ci// Note, only string wrappers can have own enumerable properties. 101425bb815Sopenharmony_ciassert (JSON.stringify (obj) === '{"0":"a","1":"b","2":"c"}'); 102425bb815Sopenharmony_ci 103425bb815Sopenharmony_ci//Exceptions will interrupt the ongoing copying task 104425bb815Sopenharmony_civar target = Object.defineProperty ({}, 'foo', { 105425bb815Sopenharmony_ci value: 1, 106425bb815Sopenharmony_ci writable: false 107425bb815Sopenharmony_ci}); // target.foo is a read-only property 108425bb815Sopenharmony_ci 109425bb815Sopenharmony_citry { 110425bb815Sopenharmony_ci // TypeError: "foo" is read-only,the Exception is thrown when assigning target.foo 111425bb815Sopenharmony_ci Object.assign (target, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 }); 112425bb815Sopenharmony_ci assert (false); 113425bb815Sopenharmony_ci} catch (e) { 114425bb815Sopenharmony_ci assert (e instanceof TypeError); 115425bb815Sopenharmony_ci} 116425bb815Sopenharmony_ci 117425bb815Sopenharmony_ciassert (target.bar === 2); // the first source was copied successfully. 118425bb815Sopenharmony_ciassert (target.foo2 === 3); // the first property of the second source was copied successfully. 119425bb815Sopenharmony_ciassert (target.foo === 1); // exception is thrown here. 120425bb815Sopenharmony_ciassert (target.foo3 === undefined); // assign method has finished, foo3 will not be copied. 121425bb815Sopenharmony_ciassert (target.baz === undefined); // the third source will not be copied either. 122425bb815Sopenharmony_ci 123425bb815Sopenharmony_ci// Copying accessors 124425bb815Sopenharmony_civar obj = { 125425bb815Sopenharmony_ci foo: 1, 126425bb815Sopenharmony_ci get bar() { 127425bb815Sopenharmony_ci return 2; 128425bb815Sopenharmony_ci } 129425bb815Sopenharmony_ci}; 130425bb815Sopenharmony_ci 131425bb815Sopenharmony_civar copy = Object.assign ({}, obj); 132425bb815Sopenharmony_ciassert (JSON.stringify (copy) === '{"foo":1,"bar":2}'); 133425bb815Sopenharmony_ciassert (copy.bar === 2); // the value of copy.bar is obj.bar's getter's return value. 134425bb815Sopenharmony_ci 135425bb815Sopenharmony_ci// This is an assign function that copies full descriptors 136425bb815Sopenharmony_cifunction completeAssign (target, sources) { 137425bb815Sopenharmony_ci sources.forEach (source => { 138425bb815Sopenharmony_ci var descriptors = Object.keys (source).reduce ((descriptors, key) => { 139425bb815Sopenharmony_ci descriptors[key] = Object.getOwnPropertyDescriptor (source, key); 140425bb815Sopenharmony_ci return descriptors; 141425bb815Sopenharmony_ci }, {}); 142425bb815Sopenharmony_ci 143425bb815Sopenharmony_ci Object.defineProperties (target, descriptors); 144425bb815Sopenharmony_ci }); 145425bb815Sopenharmony_ci return target; 146425bb815Sopenharmony_ci} 147425bb815Sopenharmony_ci 148425bb815Sopenharmony_civar copy = completeAssign ({}, [obj]); 149425bb815Sopenharmony_ciassert (JSON.stringify (copy) === '{"foo":1,"bar":2}'); 150425bb815Sopenharmony_ciassert (copy.bar === 2); 151425bb815Sopenharmony_ci 152425bb815Sopenharmony_ci// Test when target is not coercible to object 153425bb815Sopenharmony_citry { 154425bb815Sopenharmony_ci Object.assign.call (undefined); 155425bb815Sopenharmony_ci assert (false); 156425bb815Sopenharmony_ci} catch (e) { 157425bb815Sopenharmony_ci assert (e instanceof TypeError) 158425bb815Sopenharmony_ci} 159425bb815Sopenharmony_ci 160425bb815Sopenharmony_civar asd = Symbol ("asd"); 161425bb815Sopenharmony_civar foo = Symbol ("foo"); 162425bb815Sopenharmony_civar bar = Symbol ("bar"); 163425bb815Sopenharmony_civar obj = {1: 5, "a": 6, [foo]: 7, [asd]: 8, [bar]: 9}; 164425bb815Sopenharmony_civar result = Object.assign ({}, obj); 165425bb815Sopenharmony_ciassert (result[foo] == 7); 166425bb815Sopenharmony_ciassert (result[asd] == 8); 167425bb815Sopenharmony_ciassert (result[bar] == 9); 168