Function Objects, and closures (javascript)

Function definitions

Use new to create instances, you are having objects returned to you.

Thus, the objects would be referenced by t1 and t2. If you were to access property name, you’d get the results:

t1 this.name – Test1() – hooray works!

public and private

this.property is public. var properties are private.

Given a function prototype without a closure, this.property is public, while a var is private

Here comes the Closure

Now, add the function definition growls into Test2.

By adding a function inside of a function, the whole thing becomes a closure.
2 things happen:

  • the inner function now has references to the local variables, such as any variables you declare
  • Outside cannot access the object’s properties. The properties have become private.

Hence, having our reference t2.name will give us undefined:

Because this is referenced differently in functions, depending on whether:

  • object that’s attached to the function, calls the function
  • scope calls the function
  • object uses addListener, attach…etc

CLOSURE EXPLAINED

A closure is when you have a function inside of a function. It automatically sets all properties to private.

Result

Test2() Constructor: Jabba the Hut
undefined yells out hadoken

The reason why this happens is because the this of Test2() and the this are different. The this in the growls function refers to the object that’s bound to the function.

The this of the Test2() is bound to its scope only, and does not affect the this of function growls. It can be used within Test2()’s function scope only and is used privately.

The this.name in the functions use the object that the function is attached to.

You can assign public attributes to the calling object by doing t2.name = “Ken”.

Hence

would give you


Test2() Constructor: Jabba the Hut
ricky yells out hadoken

because the this in function growls is referring to the object (in our case t2), which has attribute name of “ricky”.

Using var or let

If you were to use var or let, you can access the values because by definition, the var’s scope is the closest outer functional scope, and the let’s scope is the closest enclosing block scope.


Test2() Constructor: Jabba the Hut
ricky yells out hadoken
age is: 36
type is: human

read:

http://stackoverflow.com/questions/133973/how-does-this-keyword-work-within-a-javascript-object-literal

Using ‘self’ for non strict js

If you are not using strict mode, use self and use self in your inner functions in order to use properties like OOP.

result:


Test2() Constructor: Jabba the Hut
Jabba the Hut yells out hadoken
age is: 36
type is: human

The reason why it works is because self is a var, which means var’s scope extends all the way into the inner function’s scope as well.

NOT using New…our scope becomes global


Test2() Constructor: Jabba the Hut
Ryu.. yells out hadoken
age is: 36
global.name: Jabba the Hut

So as you can see because we are NOT using new, it means the attached this reference is the global object to our Test2 function.
this.name automatically attaches the attribute name to the global object.

We put object var t2 onto the stack, and assign Test2 function to this object t2.

t2.name = “Ryu…” basically assigns the attribute name to the t2 object.

t2 object then invokes the growls function. Inside the growls function, the this refers to the object that’s invoking it, which in our case, is t2. Hence, that’s why this.name will get “Ryu”.

Using “use strict” and “=>”

Until arrow functions, every new function defined its own this value (a new object in case of a constructor.

It is undefined in strict mode function calls, the context object if the function is called as an “object method”, etc.).

This proved to be annoying with an object-oriented style of programming.

So you’ll get

“Jabba the Hut yells out hadoken”
“Jabba the Hut yells out shoooo ryu ken!”

So what’s going on

We have to see how Test2 is created. We see that we use New to create it. So right away we know 2 things:

1) Test2 object’s this is lexically scoped to itself. The this used is private and lexically scoped within Test2 only.

2) On the stack we have a reference variable called t2. It now points to the object Test2 in the heap.

In growls function, the this in that function will refer to t2’s public attributes. Hence that’s why when you use this.name, it will be ‘Ryu’, because ryu is assigned to the public name attribute as defined for t2.

using self.name will give you “Jabba the Hut” because self references the this that’s privately scoped.

In growls2 function, the this is lexically tied to the this that’s scoped for the Test2 object on the heap. IT DOES NOT TIE ‘THIS’ TO THE OBJECT THAT’S CALLING THIS FUNCTION ANYMORE’ Hence, typing the this to the private this of the object in the heap is more object oriented behavior.

Now, if the object was created like

It means Test2()’s this scope is tied to global, or window.

Thus, all the other behavior is the same. The only difference is that in Test2’s this.name, you are referring to the window or global object, and thus adding the name attribute to it.

If you go

you will see the result.