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

Commit e3ece2f

Browse files
thorn0gkalpak
authored andcommitted
feat(isArray): support Array subclasses in angular.isArray()
Closes #15533 Closes #15541 BREAKING CHANGE: Previously, `angular.isArray()` was an alias for `Array.isArray()`. Therefore, objects that prototypally inherit from `Array` where not considered arrays. Now such objects are considered arrays too. This change affects several other methods that use `angular.isArray()` under the hood, such as `angular.copy()`, `angular.equals()`, `angular.forEach()`, and `angular.merge()`. This in turn affects how dirty checking treats objects that prototypally inherit from `Array` (e.g. MobX observable arrays). AngularJS will now be able to handle these objects better when copying or watching.
1 parent 67f54b6 commit e3ece2f

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

src/Angular.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,7 @@ function isArrayLike(obj) {
219219

220220
// NodeList objects (with `item` method) and
221221
// other objects with suitable length characteristics are array-like
222-
return isNumber(length) &&
223-
(length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item === 'function');
222+
return isNumber(length) && (length >= 0 && (length - 1) in obj || typeof obj.item === 'function');
224223

225224
}
226225

@@ -635,12 +634,14 @@ function isDate(value) {
635634
* @kind function
636635
*
637636
* @description
638-
* Determines if a reference is an `Array`. Alias of Array.isArray.
637+
* Determines if a reference is an `Array`.
639638
*
640639
* @param {*} value Reference to check.
641640
* @returns {boolean} True if `value` is an `Array`.
642641
*/
643-
var isArray = Array.isArray;
642+
function isArray(arr) {
643+
return Array.isArray(arr) || arr instanceof Array;
644+
}
644645

645646
/**
646647
* @description

test/AngularSpec.js

+31
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,37 @@ describe('angular', function() {
12541254
});
12551255
});
12561256

1257+
describe('isArray', function() {
1258+
1259+
it('should return true if passed an `Array`', function() {
1260+
expect(isArray([])).toBe(true);
1261+
});
1262+
1263+
it('should return true if passed an `Array` from a different window context', function() {
1264+
var iframe = document.createElement('iframe');
1265+
document.body.appendChild(iframe); // No `contentWindow` if not attached to the DOM.
1266+
var arr = new iframe.contentWindow.Array();
1267+
document.body.removeChild(iframe); // Clean up.
1268+
1269+
expect(arr instanceof Array).toBe(false);
1270+
expect(isArray(arr)).toBe(true);
1271+
});
1272+
1273+
it('should return true if passed an object prototypically inherited from `Array`', function() {
1274+
function FooArray() {}
1275+
FooArray.prototype = [];
1276+
1277+
expect(isArray(new FooArray())).toBe(true);
1278+
});
1279+
1280+
it('should return false if passed non-array objects', function() {
1281+
expect(isArray(document.body.childNodes)).toBe(false);
1282+
expect(isArray({length: 0})).toBe(false);
1283+
expect(isArray({length: 2, 0: 'one', 1: 'two'})).toBe(false);
1284+
});
1285+
1286+
});
1287+
12571288
describe('isArrayLike', function() {
12581289

12591290
it('should return false if passed a number', function() {

0 commit comments

Comments
 (0)