/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function checkDataProperty(object, propertyKey, value, writable, enumerable, configurable) { var desc = Object.getOwnPropertyDescriptor(object, propertyKey);
assertEq(desc === undefined, false);
assertEq('value' in desc, true);
assertEq(desc.value, value);
assertEq(desc.writable, writable);
assertEq(desc.enumerable, enumerable);
assertEq(desc.configurable, configurable);
}
// Basic functionality works with multiple sources function basicMultipleSources() { var a = {}; var b = { bProp : 7 }; var c = { cProp : 8 };
Object.assign(a, b, c);
assertEq(a.bProp, 7);
assertEq(a.cProp, 8);
}
basicMultipleSources();
// Basic functionality works with symbols (Bug 1052358) function basicSymbols() { var a = {}; var b = { bProp : 7 }; var aSymbol = Symbol("aSymbol");
b[aSymbol] = 22;
Object.assign(a, b);
assertEq(a.bProp, 7);
assertEq(a[aSymbol], 22);
}
basicSymbols();
// Technically an embedding could have this as extension acting differently // from ours, so a feature-test is inadequate. We can move this subtest // into extensions/ if that ever matters. if (typeof createIsHTMLDDA === "function") { var falsyObject = createIsHTMLDDA();
falsyObject.foo = 7;
// Only [[Enumerable]] properties are assigned to target function onlyEnumerablePropertiesAssigned() { var source = Object.defineProperties({}, {
a: {value: 1, enumerable: true},
b: {value: 2, enumerable: false},
}); var target = Object.assign({}, source);
assertEq("a" in target, true);
assertEq("b" in target, false);
}
onlyEnumerablePropertiesAssigned();
// Enumerability is decided on-time, not before main loop (1) function testEnumerabilityDeterminedInLoop1()
{ var getterCalled = false; var sourceTarget = {
get a() { getterCalled = true },
get b() { Object.defineProperty(sourceTarget, "a", {enumerable: false}) },
}; var source = new Proxy(sourceTarget, { ownKeys: () => ["b", "a"] });
Object.assign({}, source);
assertEq(getterCalled, false);
}
testEnumerabilityDeterminedInLoop1();
// Enumerability is decided on-time, not before main loop (2) function testEnumerabilityDeterminedInLoop2()
{ var getterCalled = false; var sourceTarget = {
get a() { getterCalled = true },
get b() { Object.defineProperty(sourceTarget, "a", {enumerable: true}) },
}; var source = new Proxy(sourceTarget, {
ownKeys: () => ["b", "a"]
});
Object.defineProperty(sourceTarget, "a", {enumerable: false});
Object.assign({}, source);
assertEq(getterCalled, true);
}
testEnumerabilityDeterminedInLoop2();
// Properties are retrieved through Get() and assigned onto // the target as data properties, not in any sense cloned over as descriptors function testPropertiesRetrievedThroughGet() { var getterCalled = false;
Object.assign({}, {get a() { getterCalled = true }});
assertEq(getterCalled, true);
}
testPropertiesRetrievedThroughGet();
// Properties are retrieved through Get() // Properties are assigned through Put() function testPropertiesAssignedThroughPut() { var setterCalled = false;
Object.assign({set a(v) { setterCalled = v }}, {a: true});
assertEq(setterCalled, true);
}
testPropertiesAssignedThroughPut();
// Properties are retrieved through Get() // Properties are assigned through Put(): Existing property attributes are not altered function propertiesAssignedExistingNotAltered() { var source = {a: 1, b: 2, c: 3}; var target = {a: 0, b: 0, c: 0};
Object.defineProperty(target, "a", {enumerable: false});
Object.defineProperty(target, "b", {configurable: false});
Object.defineProperty(target, "c", {enumerable: false, configurable: false});
Object.assign(target, source);
checkDataProperty(target, "a", 1, true, false, true);
checkDataProperty(target, "b", 2, true, true, false);
checkDataProperty(target, "c", 3, true, false, false);
}
propertiesAssignedExistingNotAltered();
// Properties are retrieved through Get() // Properties are assigned through Put(): Throws TypeError if non-writable function propertiesAssignedTypeErrorNonWritable() { var source = {a: 1}; var target = {a: 0};
Object.defineProperty(target, "a", {writable: false});
assertThrowsInstanceOf(() => Object.assign(target, source), TypeError);
checkDataProperty(target, "a", 0, false, true, true);
}
propertiesAssignedTypeErrorNonWritable();
// Properties are retrieved through Get() // Put() creates standard properties; Property attributes from source are ignored function createsStandardProperties() { var source = {a: 1, b: 2, c: 3, get d() { return 4 }};
Object.defineProperty(source, "b", {writable: false});
Object.defineProperty(source, "c", {configurable: false}); var target = Object.assign({}, source);
checkDataProperty(target, "a", 1, true, true, true);
checkDataProperty(target, "b", 2, true, true, true);
checkDataProperty(target, "c", 3, true, true, true);
checkDataProperty(target, "d", 4, true, true, true);
}
createsStandardProperties();
// Properties created during traversal are not copied function propertiesCreatedDuringTraversalNotCopied() { var source = {get a() { this.b = 2 }}; var target = Object.assign({}, source);
assertEq("a" in target, true);
assertEq("b" in target, false);
}
propertiesCreatedDuringTraversalNotCopied();
// Properties deleted during traversal are not copied function testDeletePropertiesNotCopied() { var source = new Proxy({
get a() { deletethis.b },
b: 2,
}, {
getOwnPropertyNames: () => ["a", "b"]
}); var target = Object.assign({}, source);
assertEq("a" in target, true);
assertEq("b" in target, false);
}
testDeletePropertiesNotCopied();
function testDeletionExposingShadowedProperty()
{ var srcProto = { b: 42 }; var src =
Object.create(srcProto,
{ a: { enumerable: true, get: function() { deletethis.b; } },
b: { value: 2, configurable: true, enumerable: true } }); var source = new Proxy(src, { getOwnPropertyNames: () => ["a", "b"] }); var target = Object.assign({}, source);
assertEq("a" in target, true);
assertEq("b" in target, false);
}
testDeletionExposingShadowedProperty();
// Properties first deleted and then recreated during traversal are copied (1) function testDeletedAndRecreatedPropertiesCopied1() { var source = new Proxy({
get a() { deletethis.c },
get b() { this.c = 4 },
c: 3,
}, {
getOwnPropertyNames: () => ["a", "b", "c"]
}); var target = Object.assign({}, source);
assertEq("a" in target, true);
assertEq("b" in target, true);
assertEq("c" in target, true);
checkDataProperty(target, "c", 4, true, true, true);
}
testDeletedAndRecreatedPropertiesCopied1();
// Properties first deleted and then recreated during traversal are copied (2) function testDeletedAndRecreatedPropertiesCopied2() { var source = new Proxy({
get a() { deletethis.c },
get b() { this.c = 4 },
c: 3,
}, {
ownKeys: () => ["a", "c", "b"]
}); var target = Object.assign({}, source);
assertEq("a" in target, true);
assertEq("b" in target, true);
assertEq("c" in target, false);
}
testDeletedAndRecreatedPropertiesCopied2();
// String and Symbol valued properties are copied function testStringAndSymbolPropertiesCopied() { var keyA = "str-prop"; var source = {"str-prop": 1}; var target = Object.assign({}, source);
checkDataProperty(target, keyA, 1, true, true, true);
}
testStringAndSymbolPropertiesCopied();
// Intermediate exceptions stop traversal and throw exception function testExceptionsDoNotStopFirstReported1() { var TestError = function TestError() {}; var source = new Proxy({}, {
getOwnPropertyDescriptor: function(t, pk) {
assertEq(pk, "b"); thrownew TestError();
},
ownKeys: () => ["b", "a"]
});
assertThrowsInstanceOf(() => Object.assign({}, source), TestError);
}
testExceptionsDoNotStopFirstReported1();
if (typeof reportCompare == "function")
reportCompare(true, true);
Messung V0.5
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.