Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclassing Javascript Arrays. TypeError: Array.prototype.toString is not generic

Is it possible to subclass and inherit from javascript Arrays?

I'd like to have my own custom Array object that has all the features of an Array, but contains additional properties. I'd use myobj instanceof CustomArray to perform specific operations if the instance is my CustomArray.

After attempting to subclass and running into some problems, I found this Dean Edwards article that indicates doing this with Array objects doesn't work right. It turns out Internet Explorer doesn't handle it properly. But I'm finding other issues as well (only tested in Chrome so far).

Here's some sample code:

/**   *  Inherit the prototype methods from one constructor into another   *  Borrowed from Google Closure Library   */ function inherits(childCtor, parentCtor) {     function tempCtor() {};     tempCtor.prototype = parentCtor.prototype;     childCtor.superClass_ = parentCtor.prototype;     childCtor.prototype = new tempCtor();     childCtor.prototype.constructor = childCtor; },  // Custom class that extends Array class function CustomArray() {     Array.apply(this, arguments); } inherits(CustomArray,Array);  array = new Array(1,2,3); custom = new CustomArray(1,2,3); 

Entering the following in Chrome's console gives this output:

> custom [] > array [1, 2, 3] > custom.toString() TypeError: Array.prototype.toString is not generic > array.toString() "1,2,3" > custom.slice(1) [] > array.slice(1) [2, 3] > custom.push(1) 1 > custom.toString() TypeError: Array.prototype.toString is not generic > custom [1] 

Obviously, the objects don't behave the same. Should I give up on this approach, or is there some way to accomplish my goal of myobj instanceof CustomArray?

like image 795
Tauren Avatar asked Jul 16 '10 02:07

Tauren


People also ask

What is array method in JavaScript?

In JavaScript, Array is a built-in global object that allows you to store multiple elements at once. In this reference page, you will find all the Array methods and their properties. For example, the sort() method of an Array is used to sort all the elements of that array using default or custom sorting rules.

What is array-like object in JavaScript?

In JavaScript, arrays are created with square brackets [...], and elements are indexed. An array-like is an object. Has indexed access to the elements and a non-negative length property to know the number of elements in it. These are the only similarities it has with an array.

How do you create an array in JavaScript?

Creating an Array Using an array literal is the easiest way to create a JavaScript Array. Syntax: const array_name = [item1, item2, ...]; It is a common practice to declare arrays with the const keyword.

What is prototype in JavaScript array?

prototype allows you to add new properties and methods to arrays. prototype is a property available with all JavaScript objects.


2 Answers

Juriy Zaytsev (@kangax) just today released a really good article on the subject.

He explores various alternatives like the Dean Edwards iframe borrowing technique, direct object extension, prototype extension and the usage of ECMAScript 5 accessor properties.

At the end there is no perfect implementation, each one has its own benefits and drawbacks.

Definitely a really good read:

  • How ECMAScript 5 still does not allow to subclass an array
like image 74
Christian C. Salvadó Avatar answered Oct 09 '22 03:10

Christian C. Salvadó


ES6

class SubArray extends Array {     last() {         return this[this.length - 1];     } } var sub = new SubArray(1, 2, 3); sub // [1, 2, 3] sub instanceof SubArray; // true sub instanceof Array; // true 

Original Answer: (Not recommended, may cause performance issues)

Copy-pasting from article mentioned in the accepted answer for more visibility

Using __proto__

function SubArray() {   var arr = [ ];   arr.push.apply(arr, arguments);   arr.__proto__ = SubArray.prototype;   return arr; } SubArray.prototype = new Array; 

Now you can add your methods to SubArray

SubArray.prototype.last = function() {   return this[this.length - 1]; }; 

Initialize like normal Arrays

var sub = new SubArray(1, 2, 3); 

Behaves like normal Arrays

sub instanceof SubArray; // true sub instanceof Array; // true 
like image 39
laggingreflex Avatar answered Oct 09 '22 04:10

laggingreflex