Array.getter, .setter

Example:

/*Array.getter(array, getterFunc)*/
/*Array.setter(array, setterFunc)*/

function _get(index , thisArray){
	if (index >= thisArray.length) {
		console.log("Overflowed");
		return;
	}
	console.log("Getting index ", index, ", value : ", thisArray[index]);
	return thisArray[index];  // original getter is called here
}

function _set(value, index , thisArray){
	if (index > 3) {
		console.log("Overflowed");
		return;
	}
	if (index > thisArray.length) {
		console.log("No sparse array allowed");
		return;
	}
	console.log("Setting ", value, " at index ", index);
	thisArray[index] = value;
}

let myArray = [1, 2, 3];

Array.getter(myArray, _get);
Array.setter(myArray, _set);

myArray["0"] // "Getting index 0, value : 1"
myArray["1"] // "Getting index 1, value : 2"
myArray[2] // "Getting index 2, value : 3"
myArray[3] // "Overflowed"
myArray["00"] // undefined
myArray["01"] // undefined
myArray[4] = 3; //"No sparse array allowed"
myArray[3] = 4; //"Setting 4 at index 3"
myArray[4] = 4; // "Overflowed

It affects the performance, but it is useful for debugging. Right?

1 Like

Much simpler for the debugging use case would be to use Proxy and wrap your array.

3 Likes

Array getter/setter only handle a valid index property. You need not to consider other properties like length or its method push() etc. It should be more simpler and faster than using Proxy.

Being able to take an ordinary array and then add proxy like hooks to it makes the language harder to reason about and to implement. This is why Object.observe was removed. It's easier if the object specifies what needs to be intercepted at creation time like a Proxy.

Theoretically there could be a special Proxy.array that is optimized for only array access but this would likely require evidence that the performance win would be big enough. Modern JS engines are very complex and predicting what will be fast is difficult.

1 Like

This can be done even simpler:

class MyCoolArray extends Array {
  set(index, value) {
    return this[index] = value;
  }

  get(index) {
    return this[index];
  }
}

This is already done in Observable.

state.array.set(0, 1);

Anyway, my idea is just a rough idea that allows us to handle the index items.

Now, I am thinking that using some new keywords inside a class is better. In other words, it is better to create array like object. e.g. HTMLCollection .

Modern JS engines have optimized for indexed GetOwnProperty for well over a decade. Browsers use it heavily for stuff that can be both accessed by name and by index like the NamedNodeMap interface. V8 has long maintained integer indices separately from object indices for array-like objects.

It'd be an easy ask for them. And performance would improve significantly since implementors wouldn't have to stringify a property solely for the proxy handler to then, after some equality comparisons, parse back out to a number.