Pietro Coelho
Pietro Coelho

Reputation: 2072

Save value inside closure

I have an object which the property onProgress. This property is a function that receives the seconds as parameter, and is called everytime my player changes it's duration. What I want to do is, inside this function, create a property called oldSeconds. I wanna console.log the oldSeconds variable and the currentSeconds. In this case, oldSeconds will be always 1 second less than the current seconds.

The problem is that oldSeconds is always 0 because the function updates its value everytime it's called. It's possible to achieve this without creating the oldSeconds variable outside the function?

Object:

var opts = {
  onProgress: function(seconds) {
    var oldSeconds = 0
    return function() {
      console.log('Seconds:', seconds, 'OldSeconds:', oldSeconds)
      oldSeconds = seconds
    }
  }
}

Function is called like:

onProgress(1) // here oldSeconds should be 0
onProgress(2) // and here oldSeconds should be 1

EDIT:

I got it working. So the function should be re-write like this:

var opts = {
  onProgress: function() {
    var oldSeconds = 0
    return function(seconds) {
      console.log('seconds:', seconds,'oldSeconds:', oldSeconds)
      oldSeconds = seconds
    }
  }
}

var progress = opts.onProgress()
progress(1)
progress(2)

and so on.

The problem is that I don't want to do

var progress = onProgress()

because the onProgress function won't always be a function like that one (it can be a generic function).

So how do 'detect' that the function returns a closure and do what I want?

Upvotes: 2

Views: 1576

Answers (1)

Pointy
Pointy

Reputation: 413828

Your code is close, but the parameter is in the wrong place and you're missing the function call for the wrapper:

var opts = {
 onProgress: function() {
  var oldSeconds = 0
  return function(seconds) {
   console.log('Seconds:', seconds, 'OldSeconds:', oldSeconds)
   oldSeconds = seconds
  };
 }() // <-- call the wrapper function
}

Now the "onProgress" property will be initialized with the result of calling that anonymous function. That result will be the actual function to be invoked later as obj.onProgress(), so that's where the "seconds" parameter needs to be.

Upvotes: 1

Related Questions