2

I can easily understand how it works in C#, but in Javascript I'm a little bit confused. Here is a little test code I wrote:

  function Lunch(name,price)
  {     
    var priceChanging = [], priceChanged = [];

    this.name = function(val)
    {
        return name;
    }
    this.price = function(val)
    {
        if(val !== price && val !== undefined )
         {
            for(var i = 0; i < priceChanging.length; i++)
            {
                if(!priceChanging[i](this,val))
                {
                    return price;
                }                   
            }
            price = val;
            for(var i = 0; i < priceChanged.length; i++)            
              { 
                priceChanged[i](this);
              }     
         }
        return price;
    }

    this.OnPriceChanging = function(val)    
    {
         priceChanging.push(val);
    }
    this.OnPriceChanged = function(val)     
    {
         priceChanged.push(val);
    }
 }

var order = new Lunch("Fish and Chips",20);

console.log(order.name());
console.log(order.price());

order.OnPriceChanging(function(name,price)
{
    if(price > 30)
    {
        console.log("Price too high");
        return false;
    }
    return true;

});

order.OnPriceChanged(function(name)
{
    console.log("Price changed to: $" + name.price());
});

It runs fine, the thing is I want to be able to explain it to myself. I'm not in front of a debugger and just used Notepad at the moment. I just thought of it like .NET where subscribers are put in a container, I'm just curious how it works in Javascript.

Does the OnPriceChanging and OnPriceChanged function call themselves automatically anytime you add/change the price? I guess I'm just uncomfortable with how Javascript is loosely typed and all.

As always, I'm very thankful for all the imparted knowledge.

  • Possible duplicate of [JavaScript custom Event Listener](http://stackoverflow.com/questions/9671995/javascript-custom-event-listener) – chenop Apr 21 '16 at 06:14

1 Answers1

2

It's really quite simple. You have two arrays that store functions:

var priceChanging = [], priceChanged = [];

You have two methods that push functions into the arrays:

this.OnPriceChanging = function(val)    
{
     priceChanging.push(val);
}
this.OnPriceChanged = function(val)     
{
     priceChanged.push(val);
}

You then push functions into the arrays:

order.OnPriceChanging(function(name,price)
{
    if(price > 30)
    {
        console.log("Price too high");
        return false;
    }
    return true;
});

order.OnPriceChanged(function(name)
{
    console.log("Price changed to: $" + name.price());
});

Note that the code above may be confusing if you're not used to seeing anonymous functions. They are exactly equivalent to this:

function priceChangingCallback (name,price)
{
    if(price > 30)
    {
        console.log("Price too high");
        return false;
    }
    return true;
}

function priceChangedCallback (name)
{
    console.log("Price changed to: $" + name.price());
})

order.OnPriceChanging(priceChangingCallback);
order.OnPriceChanged(priceChangedCallback);

So you see, the arrays priceChanging and priceChanged should now both contain a single function each.

Does the OnPriceChanging and OnPriceChanged function call themselves automatically anytime you add/change the price?

No, they do not. In fact to be precise, it's not OnPriceChanging and OnPriceChanged that are called. It's functions inside the arrays priceChanging and priceChanged. And they don't call themselves. You called them:

this.price = function(val)
{
    if(val !== price && val !== undefined )
     {
        for(var i = 0; i < priceChanging.length; i++)
        {
            if(!priceChanging[i](this,val)) // <--- you're calling it here!!
            {
                return price;
            }                   
        }
        price = val;
        for(var i = 0; i < priceChanged.length; i++)            
          { 
            priceChanged[i](this); // <-- you're calling it here!!
          }     
     }
    return price;
}

You're calling all functions inside priceChanging and priceChanged arrays inside for loops. Functions that you added to the arrays using the OnPriceChanging and OnPriceChanged methods.

slebetman
  • 109,858
  • 19
  • 140
  • 171
  • Thanks for the answer. What's confusing me is I only called those once, yet when I put order.price() for x number of times, those functions get called again? without me explicitly calling it. – Practical Programmer Apr 21 '16 at 06:22
  • What do you mean by "those"? Like I mentioned above, you aren't calling the functions once, you're calling them inside the for loops inside the `price` method. So every time you call `price()` you also call `priceChanged[i](this)` – slebetman Apr 21 '16 at 07:03
  • The thing to get used to is that functions are also objects that can be treated like variables. I'm not sure about C# but this is a normal language feature in most languages these days. – slebetman Apr 21 '16 at 07:06
  • I see.. It was the absence of those names and types that I'm used to in C# that's confusing..thanks again! – Practical Programmer Apr 21 '16 at 08:32