diff --git a/src/Angular.js b/src/Angular.js index 8daf1e417140..a08bda672099 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -772,7 +772,8 @@ function copy(source, destination, stackSource, stackDest) { } else if (isRegExp(source)) { destination = new RegExp(source.source); } else if (isObject(source)) { - destination = copy(source, {}, stackSource, stackDest); + var emptyObject = Object.create(Object.getPrototypeOf(source)); + destination = copy(source, emptyObject, stackSource, stackDest); } } } else { @@ -807,12 +808,14 @@ function copy(source, destination, stackSource, stackDest) { delete destination[key]; }); for ( var key in source) { - result = copy(source[key], null, stackSource, stackDest); - if (isObject(source[key])) { - stackSource.push(source[key]); - stackDest.push(result); + if(source.hasOwnProperty(key)) { + result = copy(source[key], null, stackSource, stackDest); + if (isObject(source[key])) { + stackSource.push(source[key]); + stackDest.push(result); + } + destination[key] = result; } - destination[key] = result; } setHashKey(destination,h); } diff --git a/test/AngularSpec.js b/test/AngularSpec.js index 5d75eb1dca41..fea74f81212a 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -24,6 +24,16 @@ describe('angular', function() { expect(copy([], arr)).toBe(arr); }); + it("should preserve prototype chaining", function() { + var GrandParentProto = {}; + var ParentProto = Object.create(GrandParentProto); + var obj = Object.create(ParentProto); + expect(ParentProto.isPrototypeOf(copy(obj))).toBe(true); + expect(GrandParentProto.isPrototypeOf(copy(obj))).toBe(true); + var Foo = function() {}; + expect(copy(new Foo()) instanceof Foo).toBe(true); + }); + it("should copy Date", function() { var date = new Date(123); expect(copy(date) instanceof Date).toBeTruthy();