0

I have some functions that only return values if some underlying 'stuff' in the dom has changes, as so:

    function getFoo() {

        if (typeof this.prev === "undefined") {
            this.prev = null;
        }
 // calculate x

        if (x != this.prev) {
            this.prev = x;
        return this.prev;
        } else {
        return;
        }
    }

foo returns none if the computer var x hasnt changed. This seems to work fine when called from the console.

Next, I wrapped this in an object so i could sequentially call similar functions:

function bar () {
    this.plugins = {
        foo: getFoo
    };

    for (var attr in this.plugins) {
        if (this.plugins.hasOwnProperty(attr)) {
            console.log(this.plugins[attr]());
        }
    }

The strange thing is that when I call bar() now, the underlying functions (such as getFoo) always return values -- even if the underlying stuff in the dom hasnt changed. it seems that the functions are destroyed upon use (in the plugin object) -- how can i persist these?

3
  • can you give an example of when/how you call bar()? Commented May 5, 2011 at 15:11
  • 1
    FYI, functions always return a value; just return will return undefined. Commented May 5, 2011 at 15:12
  • 1
    Your description is very lacking, without showing more code and more context it's almost impossible to know what context this has in all these functions. And I would bet my bottom dollar that it's a this scope issue. Try changing the invoking of those function to .call(this) Commented May 5, 2011 at 15:18

2 Answers 2

1

Well, when you call bar(), it calls

this.plugin.getFoo();

so this inside getFoo will reference this.plugins.

You initialize this.plugin with a new object every time you call bar():

this.plugins = {
    foo: getFoo
};

Honestly your structure seems to quite confusing. Do you know that this inside the bar() function refers to the window object? You are "polluting" the global namespace with that. Same for getFoo if you are calling it directly.

Maybe you should have more something like this:

var bar = {
    plugins: {foo: getFoo},
    run: function() {
        for (var attr in this.plugins) {
            if (this.plugins.hasOwnProperty(attr)) {
                console.log(this.plugins[attr]());
            }
        }
    }
};

the you can call:

bar.run();

Another way of having persistent and private data between function calls is to use a closure:

var getFoo = (function() {
    var prev = null;

    return function(x){
        if (x != prev) {
            prev = x;
            return prev;
        }
    }
}());

Here the function return by the immediate function closes over prev. No matter where you assign getFoo it will have always access to prev and it does not overwrite any other prev variable in some other scope.

I think it is also better when you pass x to the function.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you - its sort of hard to explain the whole context, but i think the function closure refactor will work!
1

So everytime you call "bar()" you are overwriting the plugins attribute of your object. Just put a simple check in before redefining the plugins attribute, like this:

function bar () {
  if (typeof this.plugins === "undefined") {
    this.plugins = {
      foo: getFoo
    };
  }

  for (var attr in this.plugins) {
      if (this.plugins.hasOwnProperty(attr)) {
          console.log(this.plugins[attr]());
      }
  }
...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.