PDA

View Full Version : OO JavaScript confusion



SeaSharp
17 Oct 2007, 6:15 AM
After 2 weeks of Ext application development I decided I had to stop and REALLY understand how OO techniques are expressed in JavaScript code.

The following Crockford example is confusing me. In the constructor function "this" is assigned to "var that"? My understanding of the code is a "this" reference is being assigned to a private static class variable which will lead to trouble surely?


function Container(param) {

function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
//**********
var that = this;
//**********
this.service = function () {
if (dec()) {
return that.member;
} else {
return null;
}
};
}
.

http://www.crockford.com/javascript/private.html

pyrolupus
17 Oct 2007, 6:35 AM
He explains it right below the block of code:

By convention, we make a private that parameter. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.

Edit: Why is this possible? Same page:


This pattern of public, private, and privileged members is possible because JavaScript has "closures." What this means is that an inner function always has access to the vars and parameters of its outer function, even after the outer function has returned.

Pyro

SeaSharp
17 Oct 2007, 7:28 AM
He explains it right below the block of code:
My issue involves my misunderstanding about how to declare private static and instance variables? The table at the end of the following link indicates that "var that = this" would put this in a static variable.

http://www.webcom.it/blog/articles/2006/05/24/private-static-members-in-javascript

Extract...

[PHP]private static variable

var TEST = (function() {
var secret =

andrea.campi
17 Oct 2007, 1:20 PM
[QUOTE=SeaSharp;74586]My issue involves my misunderstanding about how to declare private static and instance variables? The table at the end of the following link indicates that "var that = this" would put this in a static variable.

http://www.webcom.it/blog/articles/2006/05/24/private-static-members-in-javascript

Extract...

[PHP]private static variable

var TEST = (function() {
var secret =

tof
17 Oct 2007, 1:36 PM
Thanks for this interesting article !

Another correction I suppose :


Note: The function statement

function membername(...) {...}

is shorthand for

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


Shouldn't last line be :
var membername = function(...) {...};

SeaSharp
17 Oct 2007, 2:35 PM
Andrea thankyou for getting involved. In general I like the systematic layout of your page showing how to implement individual OO concepts. Many JavaScript tutorials seem to wonder between, static, instance and singleton code examples without clarification.

I need to investigate JS closures further to get my head around this whole subject, hopefully the book Pro Javascript Techniques which arrives tomorrow via express delivery will help me.

fizzix5001
18 Oct 2007, 9:15 AM
Thanks for this interesting article !

Another correction I suppose :


Note: The function statement

function membername(...) {...}

is shorthand for

var membername = function membername(...) {...};
Shouldn't last line be :
var membername = function(...) {...};


There is nothing wrong with the code above and it is, in fact, the correct longhand. Defining the function membername() in the shorthand convention actually creates a variable name in the current scope then assigns the function reference to it, thereby allowing the function to refer to itself during the parsing phase. Now things get a little confusing. Consider the following snippet of code:


var ted = function bob(...){...};
ted(); //this executes fine
bob(); //this throws an exception because bob is undefined

One would expect that the function bob() now exists and the variable ted simply references the function bob(). This is not correct. As we can see (and you can try this out) bob() is undefined outside of the function body while ted() works fine. What's going on? In the above syntax, the parser is parsing the function definition for bob and in the interim, assigns a temporary variable bob to point back to itself (bob in now essentially shorthand for arguments.callee in the function body) while ted has not yet been assigned to and, therefore, will have a value of 'undefined' within the function body of bob(). Therefore, once the function is done parsing, bob is no longer in scope and now ted points to the returned function reference. This is made clear in the following example:


Example 1:

var bob = function(){
var holdit = bob;
return function(){ alert(holdit); }
}();

bob(); //alerts undefined

Example 2:
var bob = function bob(){
var holdit = bob;
return function(){ alert(holdit); }
}();

bob(); //alerts the stringified function body of bob() above;



I hope that helps

mystix
18 Oct 2007, 9:59 AM
Shouldn't last line be :
var membername = function(...) {...};

that's different -- in this case you're defining an anonymous function and then assigning it to the variable reference membername, as opposed to what @fizzix5001 has described above (i.e. the "longhand" way of defining a named function).

tof
18 Oct 2007, 10:55 AM
Sorry, but... I'm lost !

foo = function() {}
function foo() {}

Are they different ?
If yes, are they different :
- in scope / closure ? is foo(args) callable on the same places, with the same results ?
- in definition only, second way being an anonymous function (which has real difference only in stack traces debuggage, not in code behaviour) ?

( Thanks for bearing with my JS Enlightenement and my poor english skills ;) )

mystix
18 Oct 2007, 11:22 AM
yes they're different.

try the following little exercise:

this works


Ext.onReady(function() {
addThem(1, 2);

function addThem(a, b) {
var x = a + b;
alert(x);
}
});


but this fails


Ext.onReady(function() {
addThem(1, 2);

var addThem = function(a, b) {
var x = a + b;
alert(x);
};
});


go figure. have fun ;)

dtaylor
18 Oct 2007, 6:24 PM
I believe the reason the second example fails is because the anonymous function is assigned to the variable "addThem" AFTER you're trying to invoke it. When creating a named inner function, it's parsed and assigned to the variable "addThem" before the body of the outer function is run.


yes they're different.



Ext.onReady(function() {
addThem(1, 2); //fails with "addThem is not a function"

var addThem = function(a, b) {
var x = a + b;
alert(x);
};
addThem(1, 2); // succeeds!
});

mystix
18 Oct 2007, 7:33 PM
I believe the reason the second example fails is because the anonymous function is assigned to the variable "addThem" AFTER you're trying to invoke it. When creating a named inner function, it's parsed and assigned to the variable "addThem" before the body of the outer function is run.

bingo =D>