Question

This is similar to two other questions I've asked today, but I'm still trying to understand how to assign variables correctly in JavaScript.

The output to my code is this:

x: 3
x: undefined // I was expecting 3 here

And here's my code:

var myApplication = {};

(function() {
    function beep(x) {
        console.log('x: ' + x);
        var closure = {};
        return function() {
            console.log('return function() {');
            if (arguments.length) {
                console.log('setter: ' + x);
                closure.result = x;
            } else {
                console.log('getter: ' + closure.result);
                return closure.result;
            }
        }
    }
    myApplication.beep = beep;
})();
myApplication.beep(3);
RESULT = myApplication.beep();

I think the problem is where I say: myApplication.beep = beep; I think that I've got to assign it either via the prototype or some other way.

Was it helpful?

Solution

First of all, functions are first class citizens in javascript.

So when you do

return function() {
   console.log('return function() {');
   if (arguments.length) {
      console.log('setter: ' + x);
      closure.result = x;
   } else {
      console.log('getter: ' + closure.result);
      return closure.result;
   }
}

This function is not executed, you are only returning as the value of your beep function.

So, in our case, the only code that really gets executed is :

var myApplication = {};

(function() {
    function beep(x) {
        console.log('x: ' + x);
    }
    myApplication.beep = beep;
})();
myApplication.beep(3);
RESULT = myApplication.beep();

In this case you are only logging the first argument passed to beep, so 3 then undefined.

Now for what you want to do here, no need to use closures, or prototypes :

var myApplication = {
  x : null,
  beep : function (x) {
    if (typeof x != 'undefined') {
      this.x = x;
    } else {
      return this.x;
    }
  }
};

// set x
myApplication.beep(3);
// get x
var x = myApplication.beep();
console.log('x :', x);

I would avoid messing with closures too early.

OTHER TIPS

When you call beep(3) the first time, it's returning a function - but you aren't actually doing anything with that function. I think you might have meant this on the second-to-last line?...:

myApplication.beep = myApplication.beep(3);

As it is, I think the second call to beep is just returning another function, but with its 'x' argument set to undefined.

Also: To save some code-writing, rather than declaring and then assigning 'beep', you could write this:

myApplication.beep = function(x) { ...

Or, the whole object can be declared at once from the beginning:

myApplication = {
  beep: function(x) {
  },
  otherFn: function(y) {
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top