Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit cdf07ef

Browse files
committed
refactor(extend): apply caitp's review comments for good measure :)
Derpity doot Closes #10507
1 parent 5e927ee commit cdf07ef

File tree

2 files changed

+68
-15
lines changed

2 files changed

+68
-15
lines changed

src/Angular.js

+16-11
Original file line numberDiff line numberDiff line change
@@ -342,28 +342,33 @@ function setHashKey(obj, h) {
342342
function extend(dst) {
343343
var h = dst.$$hashKey;
344344
var argsLength = arguments.length;
345-
var isDeep = (argsLength >= 3) && (arguments[argsLength - 1] === true);
345+
var isDeep = false;
346+
if (argsLength >= 3) {
347+
var maybeIsDeep = arguments[argsLength - 1];
348+
// Secret code to use deep extend without adding hash keys to object properties!
349+
if (maybeIsDeep === true || maybeIsDeep === 0xFACECAFE) isDeep = maybeIsDeep;
350+
}
346351

347352
if (isDeep) --argsLength;
348353

349354
for (var i = 1; i < argsLength; i++) {
350355
var obj = arguments[i];
351-
if (obj) {
352-
var keys = Object.keys(obj);
353-
for (var j = 0, jj = keys.length; j < jj; j++) {
354-
var key = keys[j];
355-
var src = obj[key];
356-
357-
if (isDeep && isObject(dst[key])) {
358-
src = extend(dst[key], src, true);
359-
}
356+
if (!isObject(obj) && !isFunction(obj)) continue;
357+
var keys = Object.keys(obj);
358+
for (var j = 0, jj = keys.length; j < jj; j++) {
359+
var key = keys[j];
360+
var src = obj[key];
360361

362+
if (isDeep && isObject(src)) {
363+
if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
364+
extend(dst[key], src, 0xFACECAFE);
365+
} else {
361366
dst[key] = src;
362367
}
363368
}
364369
}
365370

366-
setHashKey(dst, h);
371+
if (isDeep !== 0xFACECAFE) setHashKey(dst, h);
367372
return dst;
368373
}
369374

test/AngularSpec.js

+52-4
Original file line numberDiff line numberDiff line change
@@ -225,18 +225,66 @@ describe('angular', function() {
225225
});
226226

227227
it('should perform deep extend when last argument is true', function() {
228-
var src = { foo: { bar: 'foobar', age: 10, nothing: null, undef: void 0 }},
228+
var src = { foo: { bar: 'foobar' }},
229229
dst = { foo: { bazz: 'foobazz' }};
230230
extend(dst, src, true);
231231
expect(dst).toEqual({
232232
foo: {
233233
bar: 'foobar',
234234
bazz: 'foobazz',
235-
age: 10,
236-
nothing: null,
237-
undef: void 0
238235
}
239236
});
237+
expect(dst.foo.$$hashKey).toBeUndefined();
238+
});
239+
240+
241+
it('should replace primitives with objects when deep extending', function() {
242+
var dst = { foo: "bloop" };
243+
var src = { foo: { bar: { baz: "bloop" }}};
244+
extend(dst, src, true);
245+
expect(dst).toEqual({
246+
foo: {
247+
bar: {
248+
baz: "bloop"
249+
}
250+
}
251+
});
252+
});
253+
254+
255+
it('should replace null values with objects when deep extending', function() {
256+
var dst = { foo: null };
257+
var src = { foo: { bar: { baz: "bloop" }}};
258+
extend(dst, src, true);
259+
expect(dst).toEqual({
260+
foo: {
261+
bar: {
262+
baz: "bloop"
263+
}
264+
}
265+
});
266+
});
267+
268+
269+
it('should not deep extend function-valued sources when deep extending', function() {
270+
function fn() {}
271+
var dst = { foo: 1 };
272+
var src = { foo: fn };
273+
extend(dst, src, true);
274+
expect(dst).toEqual({
275+
foo: fn
276+
});
277+
});
278+
279+
280+
it('should create an empty array if destination property is a non-object and source property is an array when deep-extending', function() {
281+
var dst = { foo: NaN };
282+
var src = { foo: [1,2,3] };
283+
extend(dst, src, true);
284+
expect(dst).toEqual({
285+
foo: [1,2,3]
286+
});
287+
expect(dst.foo).not.toBe(src.foo);
240288
});
241289
});
242290

0 commit comments

Comments
 (0)