1

I was trying to determine the best way to observe a variable's value and track its changes, for example 'language' or 'time-zone', then when it will be changed take some actions depending on the new value.

I thought of using setInterval, but I have many 'interval's in my website, so I don't want to overuse it, I'm worried that it may affect the user experience. Instead I found my self compelled to trigger the actions which I want to be done after the value changes in each method may change the variable's value, this is simple but makes my code a bit tightly coupled.

what do you suggest for that.

Rabih
  • 268
  • 1
  • 4
  • 16
  • One way could be to put your timezone/language change detection code in one of your existing _intervals_? – Ejaz May 10 '14 at 09:05
  • 1
    Or you could use custom events and add listeners to events like _timezoneChanged_ etc. This will remove tight coupling from your code. – Ejaz May 10 '14 at 09:07
  • If it is alright to use third party-libraries (and not only pure JavaScript), then try [Knockout.js](http://knockoutjs.com/) - it was created for such pusposes. – keenthinker May 10 '14 at 09:08
  • Put the code that modifies these variable in functions, and always use those functions to change them. Then those functions can trigger events that you can add handlers for in the rest of your application. – Barmar May 10 '14 at 09:13
  • take a look at https://gist.github.com/eligrey/384583 – semirturgay May 10 '14 at 09:16
  • possible duplicate of [Listening for variable changes in JavaScript or jQuery](http://stackoverflow.com/questions/1759987/listening-for-variable-changes-in-javascript-or-jquery) – alessandro May 10 '14 at 09:17

3 Answers3

1

It seems like Object.observe would be pretty much exactly what you need; unfortunately it is currently proposed as a "post ECMAScript 6" spec, so it will be a while until it is widely available in browsers. There are shim implementations though (e.g. here or here), which could give you the same functionality in current browsers.

An alternative approach would be wrapping the object in question in a direct proxy, but those are part of ES6, and also not widely adopted by browsers yet.

d0gb3r7
  • 775
  • 6
  • 16
0

You should use Object.prototype.watch() to track variable's change

The watch() method watches for a property to be assigned a value and runs a function when that occurs. Watches for assignment to a property named prop in this object, calling handler(prop, oldval, newval) whenever prop is set and storing the return value in that property. A watchpoint can filter (or nullify) the value assignment, by returning a modified newval (or by returning oldval).

If you delete a property for which a watchpoint has been set, that watchpoint does not disappear. If you later recreate the property, the watchpoint is still in effect.

To remove a watchpoint, use the unwatch() method. By default, the watch method is inherited by every object descended from Object.

there is not standard, but you can use the gist polifill created by eli-grey

Anyway this is a duplicate of Listening for variable changes in JavaScript or jQuery

Community
  • 1
  • 1
alessandro
  • 9,507
  • 5
  • 35
  • 46
  • `watch` is deprecated https://developer.mozilla.org/en-US/docs/Archive/Web/JavaScript/Object.watch – Paul Jul 05 '20 at 15:16
0

In languages like C++, you'd do this with accessor methods.

For example, instead of accessing a property of a class with something like foo.bar, you'd say foo.getBar().

getBar() would look something like this:

this.getBar = function(){
    console.log("bar was accessed");
    return bar;
}

You should also have a method to set the value of bar, i.e.

this.setBar = function(newBar){
    console.log("Setting the value of bar");
    bar = newBar;
}

These methods will give you more control of your variables, too. For example, if someone tries to assign a string to something that should be an integer, you could throw an error. Or if you have a variable called "length", you could throw an error if someone tries to make it less than zero.

Meredith
  • 834
  • 6
  • 15