5

I have the following javascript :

            var MyObject = (function() {

                function Setup(args) {
                    this.prop1 = args.x;
                    this.prop2 = args.y
                    this.prop3 = this.prop1 + this.prop2;

                    this.Create = function() {
                        return 'a' + helperFunc();
                    }

                    function helperFunc() {
                        return this.prop3;
                    }
                }

                return {
                    init : function(args) {
                        var setup = new Setup(args);

                        setup.Create();
                    }
                }

            })();


            $(function() {

                MyObject.init(someArgs);

            });
  1. Is my approach to object construction a good practice?

  2. I am getting undefined in the helperFunc when trying to access this.prop3.

  3. I have also tried to assign this.prop1 + this.prop2 to a local variable and use a function to return this value like so:

            function Setup(args) {
                    var total;
    
                    this.prop1 = args.x;
                    this.prop2 = args.y
    
                    total = this.prop1 + this.prop2;
                    this.getTotal = function() {
                            return total;
                    };
    
                    this.prop3 = this.prop1 + this.prop2;
                    ...
    

...and when calling this in the helperFunc like this:

                       return this.getTotal();

.. i get this.getTotal is not a function

I have been reading around object creation and using closures to mimic private members and so on and since there is no one way to define objects I am getting confused.

TBH - I don't really understand the construct:

                       var myObject = (function() { ... } ();

I've seen it used a lot in jQuery plugins but what does the first parenth followed by empty parenth at the end mean and do?

Any knowledge imparted would be much appreciated.

Also, I have on order the Douglas Crockford book on javascript and until it arrives I need to try to solve this problem

Alan Alcock
  • 787
  • 1
  • 11
  • 26
  • 1
    http://stackoverflow.com/questions/3921922/what-does-this-mean-function-x-y-a-b-in-javascript – mplungjan May 17 '11 at 12:25
  • There are a lot of questions here. It would make it a lot easier to provide accurate and precise answers if you try to limit yourself to one question per question. – Paul Butcher May 17 '11 at 12:32
  • mplungjan - that is a perfect link to understanding the parenth at the end of a function call. I just need to understand why I'm getting undefined when calling a property and not a function when calling a function... – Alan Alcock May 17 '11 at 12:40

4 Answers4

4

To cite Xhalent's wonderful article (really well done and clearly wirtten) mentioned by him:

That is because the value of “this” is different to the value of “this” when the object was created.

So in your case:

...
  var _this = this.prop3;
  function helperFunc() {
    return _this;
  }
...

might achieve what's desired.

ofi
  • 364
  • 1
  • 4
  • This is the answer to why i'm getting undefined. I wish i could mark Paul Butchers answer as well because that helps understand the problem. I have read Xhalent's articles and they are very useful. Setting the value to a private variable I was unaware that I could access that from the helperFunc function. I've spent too much time on c# and need to stop thinking classic oop. Look forward to Douglas Crockford's book. Thank you everyone who answered.... – Alan Alcock May 17 '11 at 13:32
1

I've done a series on basic javascript fundamentals - objects and prototypes are covered here:

Javascript Object Instantation and Prototypes

I delve into Closures here:Javascript Closures

Hope they help. Cheers.

Xhalent
  • 3,914
  • 22
  • 21
1

If you have a function that uses this, you must make sure that the calling context is correct. i.e. use this.helperFunc(), not just helperFunc() (but you'll also need to set things up so that this.helperFunc is defined). The referent of this inside helperFunc in your example is not the same as it is in Create().

You can think of it as though functions are not defined as members of objects, but called as members of objects.

There are three things that this might resolve to, depending on context.

  1. A newly created object, if the function call was preceded by the new keyword.
  2. The Object to the left of the dot when the function was called.
  3. The Global Object (window), if neither of the above are provided.

If a function is called without an object, as in the case of your call to helperFunc in this.Create, this will be bound to the global object (window, when used in a browser)

Given something like this:

var o = {someVal:"hello"};
o.doSomething = function (){alert(this.someVal)};

Calling o.doSomething() will obviously alert "hello".

Given:

var o2  = {someVal:"world"};
o2.someFunc = o.doSomething;

Calling o2.someFunc() will alert "world", not "hello", as you would expect if it were a pointer to the doSomething member of o.

And given:

var someFunc = o.doSomething
someVal = "sailor"

Calling someFunc() will alert "sailor".

Another point of confusion is the use of this directly within Setup(). When you call a function using new, as you have done, this is not bound to the global object, but to a new instance of the Setup object.

For my example above, this means that calling new o.doSomething() will alert "undefined", as the new object that has been created for the call does not have a "someVal" member.

Paul Butcher
  • 6,902
  • 28
  • 39
0

You have a good tutorial by Mike Koss on OOP in JS on this page.

I've seen it used a lot in jQuery plugins but what does the first parenth followed by empty parenth at the end mean and do?

The second set of parenth immediatly invokes the function you have declared in the first set of parenth.

You could declare it and execute it separatly (allows to execute multiple times):

var myFunction = function() { alert("boo"); }; // Declare & instanciate
myFunction(); // Invoke
myFunction(); // Invoke again

Or do both in one line:

(function() { alert("boo"); })(); // Can only invoke now, the function is anonymous and not stored anywhere.
Vincent Mimoun-Prat
  • 28,208
  • 16
  • 81
  • 124