Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to define getters for lazy variables in Javascript arrays?

I'm trying to add elements to an array that are lazy-evaluated. This means that the value for them will not be calculated or known until they are accessed. This is like a previous question I asked but for objects.

What I ended up doing for objects was

Object.prototype.lazy = function(var_name, value_function) {
  this.__defineGetter__(var_name, function() {
    var saved_value = value_function();
    this.__defineGetter__(var_name, function() {
      return saved_value;
    });
    return saved_value;
  });
}

lazy('exampleField', function() {
  // the code that returns the value I want
});

But I haven't figured out a way to do it for real Arrays. Arrays don't have setters like that. You could push a function to an array, but you'd have to call it as a function for it to return the object you really want. What I'm doing right now is I created an object that I treat as an array.

Object.prototype.lazy_push = function(value_function) {
  if(!this.length)
    this.length = 0;
  this.lazy(this.length++, value_function);
}

So what I want to know is, is there a way to do this while still doing it on an array and not a fake array?

UPDATE: The following function works only if the value_function returns a primitive data type.

Array.prototype.lazy_push = function(value_function) {
  var a = this,
  i = this.length;
  this.push({
    toString: function() {
      return a[i] = value_function();
    }
  });
}

If you try to push say an object that has properties in it, you won't be able to access the properties until you access the object directly. This doesn't happen with setters, that's why I want some kind of setting syntax for Javascript. For now I will be using the fake array, which is enough for what I'm doing.

like image 409
fent Avatar asked Jun 01 '10 19:06

fent


People also ask

What does .get do in JavaScript?

get() method in JavaScript is used to allow users to get the property from an object as a function. This method always returns the value of the property.

What is a LazyValue?

public static interface UIDefaults.LazyValue. This class enables one to store an entry in the defaults table that isn't constructed until the first time it's looked up with one of the getXXX(key) methods. Lazy values are useful for defaults that are expensive to construct or are seldom retrieved.

What is a getter method in JavaScript?

Getters give you a way to define a property of an object, but they do not calculate the property's value until it is accessed. A getter defers the cost of calculating the value until the value is needed.

What is setter and getter in JavaScript?

In JavaScript, accessor properties are methods that get or set the value of an object. For that, we use these two keywords: get - to define a getter method to get the property value. set - to define a setter method to set the property value.


2 Answers

In 2019, you could use a Proxy.

Here is an example which assumes any value which is a function should be evaluated when accessed.

function LazyArray() {
  return new Proxy([], {
    get: (obj, prop) => {
      if (typeof obj[prop] === 'function') {
        // replace the function with the result
        obj[prop] = obj[prop]()
      }
      return obj[prop]
    },
  })
}

const a = LazyArray()

a[0] = () => {
  console.log('calculating...')
  return 42
}

console.log(a[0]) // lazy evaluated
console.log(a[0])

console.log(a.length) // accessing other properties
like image 126
thedude Avatar answered Oct 01 '22 10:10

thedude


There is not. Unfortunately this is a big deal.

like image 29
orokusaki Avatar answered Oct 01 '22 10:10

orokusaki