1

I have a a variable, which always is an integer, that increases and/or decreases in value from time to time, goes from 1-5. I wanted to know if I can, in any way, detect if it goes up or down, for example:

The variable is currently at three, if it increases to four, it runs a function, but if it decreases to two, it runs another function.

Can that be done?

NepsName
  • 109
  • 1
  • 3
  • 10
  • You'll need another variable to compare if against, and exactly how you'd do this depends greatly on how you're using it, how you're increasing and decreasing the value, and probably a lot of other shit – adeneo Jan 14 '14 at 22:20
  • 1
    It would be better to hook into whatever is changing the value, either by making it trigger an event or overriding/modifying it. – Kevin B Jan 14 '14 at 22:20
  • Not reliably across browsers, unless you're using an MVC framework (and all the complexity it brings). It would be more appropriate to have whatever code is changing the variable *also* run the function. – Blazemonger Jan 14 '14 at 22:20
  • The only thing i could think of is `setInterval` and check the variable with an older version... – Mathlight Jan 14 '14 at 22:21
  • See [this answer](http://stackoverflow.com/a/4631917/165154) – Decent Dabbler Jan 14 '14 at 22:24
  • Did any of the answers work? – Cilan Feb 02 '14 at 14:09
  • Duplicate of [In javascript, how to trigger event when a variable's value is changed?](http://stackoverflow.com/questions/10638769/in-javascript-how-to-trigger-event-when-a-variables-value-is-changed) – Dan Dascalescu Aug 30 '16 at 06:36

7 Answers7

7

The following four methods will work depending on support by browser compatibility, and this post did take me a while, but it also taught me what ___ does, and I hope I listed most methods, and if you know more, you could post an answer. However, it would be greatful of you to post your method in the comments so I can add it to this answer. Cheers!


1 Use Object.observe:

Object.observe(i, function(b){ b.object[change.name] > b.type ? console.log('decreased') : console.log('increased'); });

Additional notes about Object.observe

If you like to enable it in Chrome 33,

Visit chrome://flags/

And enable Enable Experimental JavaScript


2 Use setInterval:

var i = 4;
var a = i;
setInterval(function()
{
    if(i != a) a > i ? console.log('decreased') : console.log('increased');
}, 1000);
i = 10;

should log 'increase' in one second.


3 Use Object.watch:

var i = {i:5};
i.watch("i", function (id, oldval, newval) {
    newval > oldval ? console.log('decreased') : console.log('increased');
    return newval;
});

Additional notes about Object.watch

To support more browsers, add this script:

if (!Object.prototype.watch) {
    Object.defineProperty(Object.prototype, "watch", {
          enumerable: false
        , configurable: true
        , writable: false
        , value: function (prop, handler) {
            var
              oldval = this[prop]
            , newval = oldval
            , getter = function () {
                return newval;
            }
            , setter = function (val) {
                oldval = newval;
                return newval = handler.call(this, prop, oldval, val);
            }
            ;

            if (delete this[prop]) { // can't watch constants
                Object.defineProperty(this, prop, {
                      get: getter
                    , set: setter
                    , enumerable: true
                    , configurable: true
                });
            }
        }
    });
}

// object.unwatch
if (!Object.prototype.unwatch) {
    Object.defineProperty(Object.prototype, "unwatch", {
          enumerable: false
        , configurable: true
        , writable: false
        , value: function (prop) {
            var val = this[prop];
            delete this[prop]; // remove accessors
            this[prop] = val;
        }
    });
}

obtained from https://gist.github.com/eligrey/384583


4. Use a custom value set function:

i = 4;

function setValue(obj, val)
{
    val < obj ? console.log('decrease') : console.log('increase');
    obj = val;
}

setValue(i, 10);

should log 'increase'.


Most of these require the variable to be an Object, so I'd rather detect over time as seen in method 2.

Cilan
  • 10,658
  • 3
  • 31
  • 51
1

Sure, but you'll have to check it periodically. Since you didn't provide code, I won't, either. :-)

  1. Set a second variable equal to the first
  2. Check the second against the first at regular intervals (or upon some event)
  3. Respond accordingly

As was mentioned in the comments, there are better ways, such as running functionality alongside (or as a callback to) whatever changes the variable's value in the first place.

isherwood
  • 46,000
  • 15
  • 100
  • 132
0

Rather than detecting if a variable changes, I would use a function to modify the variable. That way, the function can then check if the value has changed and call the new function if it has. Something like:

var triggerVariable;

function changeVariable(newVal){
    if(triggerVariable !== newVal){
        triggerVariable = newVal;
        callFunction();
    }
}

function callFunction(){
    alert('variable changed!');
}

changeVariable(10);
maxedison
  • 16,472
  • 13
  • 57
  • 104
0

Object.observe is supposed to be well supported. You can track your state as you please (probably in a closure of some sort).

http://updates.html5rocks.com/2012/11/Respond-to-change-with-Object-observe

D. Patrick
  • 2,565
  • 21
  • 32
0

you can also create a class for this special variable, and write custom functions for mathematical functions with callback. here is an example with the add function

function specVal (value) 
{
  this.onChange = null;
  this.value = value;
  this.val = function() 
  {
    return this.value;
  };

  this.add = function(i)
  {  
    this.value += i;
    if (this.onChange != null)
      this.onChange(this);
    return this;
  }
}

function somethingChanged(val)
{
  alert('changed: ' + val.val());
}

myValue = new specVal(10);
myValue.onChange = somethingChanged;
myValue.add(5);
myValue.add(4);
0

I would either use an MV* framework as suggested (knockout is a lightweight option) or never change the variable directly. Use a setter function that changes its value and triggers a custom event each time. JQuery example:

Function setMyVar(val){  
    if(_myVar  !== val){
    _myVar = val;
    $('#anyelement').triggerHandler('myvarupdated', [myVar]);
    }
}
CodeToad
  • 4,346
  • 4
  • 37
  • 51
0

Very similar to prior answers.

  1. Set a second variable equal to the first
  2. Check the second against the first at regular intervals (or upon some event)
  3. Respond accordingly

But organise it differently. And make sure you leave the last variable outside of the function. Moreover, at the end of your if conditional statements update the value for the one being checked for changes.

Hope it helps!

var lastValue = 0;
$(function () {


    if (lastValue > originalValue){
        console.log ("Increasing");
    }
    else if (lastValue < originalValue) {
        console.log("Decreasing");
    }
    lastValue = originalValue;            

});

Check this JSFiddle

ElGavilan
  • 5,747
  • 16
  • 24
  • 35
Trinker
  • 73
  • 9