OOP var foo vs this.foo

C

ceh

Can anyone explain if there is a difference here?
I'm lost, Thanks.

I have a class that works...

function CXMLHTTP()
{
var xmlhttp;
//this.m_xmlhttp;
this.url = "";
this.m_Response = "";

this.init = init;
this.submit = submit;
this.onReadyStateChange = onReadyStateChange;

alert( "CXMLHTTP Constructor" );

function init()
{
try
{
// Firefox, Opera 8.0+, Safari
xmlhttp = new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("Your browser does not support AJAX!");
return false;
}
}
}
}

function onReadyStateChange()
{
if( xmlhttp.readyState == 4 )
{
this.m_Response = xmlhttp.responseText;
alert( "Response = " + this.m_Response );

}
}

function submit( myurl )
{
alert( "start submit" );
xmlhttp.open("POST", myurl, true);
xmlhttp.send(null);
alert( "end submit" );
}

this.init();
xmlhttp.onreadystatechange = this.onReadyStateChange;


}

But if I change it, as I'd like to, to this
( note that the var xmlhttp is now this.m_xmlhttp )


function CXMLHTTP()
{
//var xmlhttp;
this.m_xmlhttp;
this.url = "";
this.m_Response = "";

this.init = init;
this.submit = submit;
this.onReadyStateChange = onReadyStateChange;

alert( "CXMLHTTP Constructor" );

function init()
{
try
{
// Firefox, Opera 8.0+, Safari
this.m_xmlhttp = new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
this.m_xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
this.m_xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("Your browser does not support AJAX!");
return false;
}
}
}
}

function onReadyStateChange()
{
if( this.m_xmlhttp.readyState == 4 )
{
this.m_Response = this.m_xmlhttp.responseText;
alert( "Response = " + this.m_Response );

}
}

function submit( myurl )
{
alert( "start submit" );
this.m_xmlhttp.open("POST", myurl, true);
this.m_xmlhttp.send(null);
alert( "end submit" );
}

this.init();
this.m_xmlhttp.onreadystatechange = this.onReadyStateChange;


}

I get these errors.
if( this.m_xmlhttp.readyState == 4 )
for the line in onReadyStateChange

Error: this.m_xmlhttp has no properties
Source File: http://localhost/js/CXMLHTTP.js
Line: 47

Why isn't this working?

Is there something special about the onReadyStateChange callback?
does using var change the scope of the variable for this class
somehow?
It all seems ok, except in the callback function.

Thanks
 
T

Thomas 'PointedEars' Lahn

ceh said:
[...]
I have a class

No, you don't. http://javascript.crockford.com/javascript.html
that works...

function CXMLHTTP()
{
var xmlhttp;

You declare a variable here.
//this.m_xmlhttp;

This does nothing.
[...]
}

But if I change it, as I'd like to, to this
( note that the var xmlhttp is now this.m_xmlhttp )

No, it is not.
function CXMLHTTP()
{
//var xmlhttp;

You are not even declaring the variable here.
this.m_xmlhttp;

This does nothing but to evaluate to `undefined'.
}

I get these errors.
if( this.m_xmlhttp.readyState == 4 )
for the line in onReadyStateChange

Error: this.m_xmlhttp has no properties
Source File: http://localhost/js/CXMLHTTP.js
Line: 47

Why isn't this working?

`undefined', the sole value of the `Undefined' type, has no properties.


PointedEars
 
C

ceh


OK... I have an object...
and... I don't really understand OOP in JS. I will re-read that link

Perhaps I should have written
this.m_xmlhttp = "";
and later set it to xmlhttp _object_ instance.
in fact, why do people use this at all? Those vars will be in scope
regardless correct?

If I can't declare variables via this.x = something, then why do all
my other uses of it work?
this.url = "";
For instance.

Are you suggesting that I always need var foo; ? It seems there is a
lot of code out there that uses the this methodology. If that is the
case, then is this what I'd need?

var xmlHTTP;
xmlHTTP = new ActiveXObject("Msxml2.XMLHTTP");
// use this one from now on.
this.m_xmlHTTP = xmlHTTP;

Or, just don't declare it until I set it?
this.m_xmlHTTP = new ActiveXObject("Msxml2.XMLHTTP");

In any case, it wasn't used until onReadyStateChange and by that time
it should have been initialized to something. This is where I'm
confused.

Thanks for your time.


that works...
function CXMLHTTP()
{
var xmlhttp;

You declare a variable here.
//this.m_xmlhttp;

This does nothing.
But if I change it, as I'd like to, to this
( note that the var xmlhttp is now this.m_xmlhttp )

No, it is not.


function CXMLHTTP()
{
//var xmlhttp;

You are not even declaring the variable here.
this.m_xmlhttp;

This does nothing but to evaluate to `undefined'.
I get these errors.
if( this.m_xmlhttp.readyState == 4 )
for the line in onReadyStateChange
Error: this.m_xmlhttp has no properties
Source File:http://localhost/js/CXMLHTTP.js
Line: 47
Why isn't this working?

`undefined', the sole value of the `Undefined' type, has no properties.

PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
 
V

VK

Is there something special about the onReadyStateChange callback?

Not onreadystatechange specifically but about any exit from the
execution context in JavaScript. I call this specification oops
"incontinence of [this]": being called out of the scope chain any
method doesn't remember anymore that it's a method of a particular
object so being executed as a simple stay-alone function with [this]
pointing to window. This annoyance is regularly fixed by using
internal helper variable and the value of the variable retained
between invocations using a closure. As a simple demo of the language
model default and the fix in action:

<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">

function MyObject1() {
this.property = 'something';
this.method = function() {
window.alert(this == window);
// alerts true, so no use to question
// for this.property;
}
window.setTimeout(this.method, 500);
}

function MyObject2() {
var patch = this;
this.property = 'something';
this.method = function() {
window.alert(this == window);
// still alerts true but:
window.alert(patch.property);
// alerts 'something'
}
window.setTimeout(this.method, 1000);
}

var foo = new MyObject1;
var bar = new MyObject2;
</script>
</head>
<body>
</body>
</html>
 
T

Thomas 'PointedEars' Lahn

ceh said:
Perhaps I should have written
this.m_xmlhttp = "";

Assigning `null' would be more appropriate because ...
and later set it to xmlhttp _object_ instance.

.... you would assign an object _reference_ and `null' is an object value
(the sole value of the Null type, representing "the null, empty, or
non-existent [object] reference"). But since there is no strict typing and
both values are false-values (i.e. type-convert to `false'), it does not
matter much. You could even omit the previous assignment and create the
property only when needed (there might be a bunch of warnings on prior read
access in Gecko-based UAs then, though).

I prefer initializing said properties with `null' instead of with other
false-values because it is intuitive and probably wastes a minimum amount of
memory ("" has String properties, `null' has none).
in fact, why do people use this at all? Those vars will be in scope
regardless correct?

No, this has nothing to do with variables or the scope chain. With the
above you are creating or modifying a *property* of the Activation Object.
That object is the calling object or, in the constructor, the object that
is about to be created.
If I can't declare variables via this.x = something, then why do all
my other uses of it work?
this.url = "";
For instance.

In the global execution context, the Activation Object (which `this' refers
to) is the Global Object. But the Global Object is also the Variable Object
of the global context, and so global variables are also properties of that
object. (In local execution contexts, i.e. in methods, unfortunately there
is no way to refer to the Variable Object.)

See the ECMAScript Language Specification, Edition 3 Final, sections 10.1.6
to 10.1.8, and 10.2.
Are you suggesting that I always need var foo; ?

If you want a *variable* and not just a property, then yes.
It seems there is a lot of code out there that uses the this methodology.

Maybe because of those people doing (explicit) OOP?
If that is the case, then is this what I'd need?

var xmlHTTP;
xmlHTTP = new ActiveXObject("Msxml2.XMLHTTP");
// use this one from now on.
this.m_xmlHTTP = xmlHTTP;

Or, just don't declare it until I set it?
this.m_xmlHTTP = new ActiveXObject("Msxml2.XMLHTTP");

Impossible to say without you providing the context in which these
statements are to be executed. The context matters.
[Top posting]

Please reply *below sections of trimmed quotes*, as explained and
recommended in the FAQ and FAQ Notes:

http://jibbering.com/faq/


PointedEars
 
R

Richard Cornford

Thomas said:
Assigning `null' would be more appropriate because ...
I prefer initializing said properties with `null' instead
of with other false-values because it is intuitive and
probably wastes a minimum amount of memory ("" has
String properties, `null' has none).
<snip>

On of the advantages of using - null - is that any attempt to employ a
property of the 'object' prior to the reference to the object being
assigned will error, which is what you would want to happen because that
would indicate a bug in the code which needed fixing. While assigning
to, or reading from, a property of an empty string would not error
directly (though code that did so would be likely to error elsewhere,
but probably in a way that made the cause and effect relationship of the
error harder to find.

Still, the undefined value would be as false and also error at attempts
to employ it as an object so maybe initialisation itself is unnecessary,
beyond its making an explicit statement about which properties of the -
this - object in this code were going to be used by the code. In most
cases that initialisation with - null - would be more appropriate on the
prototype of the constructor rather than in the constructor and executed
for each object instantiation.

Richard.
 
R

Richard Cornford

VK said:
Not onreadystatechange specifically

There is at least one thing that is very specific to the
onreadystatechange methods of XML HTTP request objects, in that at leas
one version of the object does not call the assigned function as a
method of the XML HTTP request object and so the - this - value in the
function does not refer to the XML HTTP request object (hence the
tendency for closures to be employed here to keep the association
between the specific XML HTTP request instance and the function assigned
to - onreadystatechange -).
but about any exit from the
execution context in JavaScript.

What does exiting an execution context (or whatever you mean be 'exit')
have to do with the - this - value?
I call this specification oops
"incontinence of [this]":

Because you don't understand how the specification is absolutely
specific about how the - this - value is determined and you don't
appreciate that no implementations are known to get this wrong.
being called out of the scope chain any
method doesn't remember anymore that it's a method of
a particular object so being executed as a simple
stay-alone function with [this] pointing to window.
<snip>

What to scope chins have to do with the - this - value?

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top