javascriptclassindexinggetproperty

Indexed getter in Javascript


I'm using straight Javascript (no JQuery or anything like that, please). I've implemented a class which wraps an array, thus:

class Ctrls
{
    _items = new Array();
        
    constructor()
    {
        this._items = new Array();
    }   
    
    Add(oCtrl)
    {
        this._items.push( { key:oCtrl.Name, value:oCtrl } );
    }   
    
    Clear()
    {
        this._items = new Array();
    }   
    
    get Count()
    {
        return this._items.length;
    }   
    
    get Item(index)
    {
        // get the index'th item. 
        // If item is numeric, this is an index.
        // If item is a string, this is a control name
        if (Number.isInteger(index))
        {
            return this._items(index).value;
        }
        else
        {
            item = this._items.find(element => (element.value.Name == index));
            return item;
        }
    }   
    
    get Items()
    {
        return this._items; // in case we desperately need to
    }
}

I get an error on page load, at get Item(index), which is Uncaught SyntaxError: Getter must not have any formal parameters. I come from C# world and am looking for an equivalent of:

public Ctrl Item(iIndex)
{
    get
    {
        return _items[iIndex];
    }
}

How do I index a getter in Javascript?


Edit(1): I've had suggestions to turn get Item into a function, but if I change the definition to this:

    function GetItem(index) // returns Ctrl
    {
        // get the index'th item. 
        // If item is numeric, this is an index.
        // If item is a string, this is a control name
        if (Number.isInteger(index))
        {
            return this._items(index).value;
        }
        else
        {
            item = this._items.find(element => (element.value.Name == index));
            return item;
        }
    }   

I get this error on pageload: Uncaught SyntaxError: Unexpected identifier at the line function GetItem...


Edit(2): Modified the above to read:

    GetItem(index) // returns Ctrl
    {
        // get the index'th item. 
        // If item is numeric, this is an index.
        // If item is a string, this is a control name
        if (Number.isInteger(index))
        {
            return this._items(index).value;
        }
        else
        {
            item = this._items.find(element => (element.value.Name == index));
            return item;
        }
    }   

as functions within classes do not use the function keyword, oddly. This now works. Thank all.


Solution

  • "you can't pass parameters to getters in JS". Theoretically: yes, you cannot do that. But practically: functions are first-class citizens in JS, so they can be arguments or return values of a function. You can do it like this:

    class GetterWithParameter {
      constructor() {
        this.array = ["index 0", "index 1", "index 2"]
      }
      get itemAtIndex() {
        return (idx) => this.array[idx]
      }
    }
    
    const getterWithParameter = new GetterWithParameter()
    
    const idx0 = getterWithParameter.itemAtIndex(0)
    const idx1 = getterWithParameter.itemAtIndex(1)
    const idx2 = getterWithParameter.itemAtIndex(2)
    
    console.log("item at index 0:", idx0)
    console.log("item at index 1:", idx1)
    console.log("item at index 2:", idx2)

    So, while the getter cannot have arguments, you can return a function that can receive an argument - and use that.

    Of course, the usage seems identical to defining a function on the class that requires the same argument - but still, you are using a getter.