最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Can I create my own array object in JavaScript? - Stack Overflow

programmeradmin2浏览0评论

I have created a JavaScript application that has a lot of array manipulations (sorting, filtering, etc.).

Currently my functions are like this:

function (myArray, arg1, arg2,...)

where myArray is the array I am working on, and arg1, arg2,... are the arguments used by the function to modify the array.

I am thinking that it would be neater to have a clear separation between the object and the arguments (a la jQuery):

myArray.function(arg1, arg2,...)

I know that I could use Array.prototype to add my function to all arrays, but this seems too heavy as the functions I add are really specific to my case and don't make sense on arrays in general. I also know that I could create an object, but then I wouldn't benefit from the array methods available in JavaScript (indexOf, filter, etc.).

Is there a way I could create my own array object, that would inherit the default array methods and allow me to add my own?

I have created a JavaScript application that has a lot of array manipulations (sorting, filtering, etc.).

Currently my functions are like this:

function (myArray, arg1, arg2,...)

where myArray is the array I am working on, and arg1, arg2,... are the arguments used by the function to modify the array.

I am thinking that it would be neater to have a clear separation between the object and the arguments (a la jQuery):

myArray.function(arg1, arg2,...)

I know that I could use Array.prototype to add my function to all arrays, but this seems too heavy as the functions I add are really specific to my case and don't make sense on arrays in general. I also know that I could create an object, but then I wouldn't benefit from the array methods available in JavaScript (indexOf, filter, etc.).

Is there a way I could create my own array object, that would inherit the default array methods and allow me to add my own?

Share Improve this question asked Feb 10, 2012 at 19:24 ChristopheChristophe 28.1k29 gold badges101 silver badges143 bronze badges 2
  • 3 keep using the function, you don't need everything in oop – dynamic Commented Feb 10, 2012 at 19:27
  • 2 Right, but I like how clean it is, for example for chaining or defining default options/arguments. – Christophe Commented Feb 10, 2012 at 19:31
Add a comment  | 

5 Answers 5

Reset to default 10

You've got two options:

Option one is to extend the Array object by adding new methods to it:

Array.prototype.myMethod = function(arg1, arg2)
{
    // Use 'this' to access the array.
}

The advantage is that every javascript array will now have this extra method. This can also be a disadvantage when multiple (external) javascript libraries try to add the same methods. Furthermore, this new method will appear in for(var item in myArray) constructs which can be problematic.

Option two is to create a "factory method" for your extended array:

function MyExtendedArray = function()
{
    var array = [];
    array.myMethod = function(arg1, arg2) {
        // Use 'this' or 'array' to access the array.
    };

    return array;
};

Now you can write this to create a new extended array:

var arr = MyExtendedArray();

No. Array cannot be subclassed and still behave like an array. Specifically, the length property will not change to reflect elements that are added or deleted from the array.

function MyArray() {}
MyArray.prototype = [];
MyArray.prototype.constructor = MyArray;
var instance = new MyArray;
instance[0] = 0;
alert(instance.length);  // alerts 0

The reason this happens is because only objects that are created via new Array or syntactic sugar like [] have the special handling around length.

The new MyArray above creates a regular object whose prototype is an Array, but there is nothing about the new operator that checks whether the prototype of an object is an Array and sets up the special length handling.

You can simply just add the function directly to your object rather than to the prototype:

var myArray = new Array();
myArray.myFunc = function(){ /* do stuff! */ };
myArray.myFunc();

i create this which is my version of array but with some modifications in this array you cant change the length like with the original array

let ary = [1,2,3];
console.log(ary.length); //3

ary.length = 999;
console.log(ary.length); //999

because i use get function to get my length and use closures for saving the value of original array length

let myArray = new MyArray(1,10); //new MyArray(from,to)
console.log(myArray.length); // 10

myArray.length = 999;
console.log(myArray.length); // 10  //still 10 because .length is a get function 

the code of my array is

let _getlength = {}, _inclength = {}, _declength = {};

class MyArray{

 constructor(from, to)
  {
    this.key = Symbol('ignore this key');

    //i make it a closer because i don't want any one to change the length
    // by this my length become private and can be only incremented by one by "_inclength()" function or
    [_getlength[this.key], _inclength[this.key], _declength[this.key]] = (
        () =>
        {
            let length = 0;

            let getLength = () =>
            {
                return length;
            };

            let inclength = () =>
            {
                length++;

                this[length - 1] = 0;

                return length;
            };

            let declength = () =>
            {
                return --length;
            };


            return [getLength, inclength, declength];
        }
    )();

    if (from != null || to != null)
    {
        for (let num = from; num <= to; num++)
        {
            this.push(num);
        }
    }

}

push(value)
{
    this[this.IncreaseLengthByOne() - 1] = value;
}

unshift(value)
{
    this.addAt(0, value)
}

addAt(index, value)
{
    this.IncreaseLengthByOne();
    for (let i = this.length - 2; i >= index; i--)
    {
        this[i + 1] = this[i];
    }

    this[index] = value;
}

removeAt(index)
{

    for (let i = index; i < this.length - 1; i++)
    {
        this[i] = this[i + 1];
    }

    this.pop();
}

pop()
{
    _declength[this.key]();
    delete this[this.length];
}

get length()
{
    return _getlength[this.key]();
}

IncreaseLengthByOne()
{
    return _inclength[this.key]();
}

forEach(callback)
{
    for (let i = 0; i < this.length; i++)
    {
        callback(this[i], i, this);
    }
}

map(callback)
{
    let myArray = new MyArray();
    for (let i = 0; i < this.length; i++)
    {
        myArray.push(callback(this[i], i, this));
    }

    return myArray;
}


// if you don't know what it is then go and learn what generators are! what Symbol(primitive type) is and what Symbol.iterator is then
// come back
* [Symbol.iterator]()
{
    for (let i = 0; i < this.length; i++)
    {
        yield this[i];
    }
}
}

examples: create an array of names and add "Ali", "Hadi", "Amber" to it

let names = new MyArray();

names.push('Ali');
names.push('Hadi');
names.push('Amber');
console.log(names); // MyArray {0: "Ali", 1: "Hadi", 2: "Amber"}

modify every name by adding there last name "Nawaz" at the end Like "Ali" become "Ali Nawaz"

let fullNames = names.map(nam => nam +' Nawaz');
console.log(fullNames); //MyArray {0: "Ali Nawaz", 1: "Hadi Nawaz", 2: "Amber Nawaz"}

Yes, just extend the Array prototype with jQuery.extend

发布评论

评论列表(0)

  1. 暂无评论