Help with classes and instance variables

S

Steve Potter

I am new to JavaScript and having a hard time understanding how to
apply OOP principals to JavaScript.

The problem I am running into is that I am binding an event callback
to an instance method, but when that method tries to access an
instance variable, it returns undefined.

I put together a quick example to demonstrate the issue I am having:

<html>
<head>
</head>
<body>
<a href="#" id="link">Click Here</a></br>

<script type="text/javascript">
function myclass(classattribute){
this.classattrib = classattribute;
this.mymethod = mymethod;
this.mymethod();
this.element = document.getElementById('link');
this.element.addEventListener('click', this.mymethod, false);

}
function mymethod(){
document.write('Class attribute = '+this.classattrib);
}

testclass = myclass('something');

</script>
</body
</html>

Essentually, the first time mymethod is executed (at page load), it
has no problem accessing this.classattrib, when it is called again as
a result of the click event, this.classattrib returns undefined.

I have tried to read some tutorials, I am finding it all very
confusing because it seems that everything in javascript can be done 3
or 4 different ways.

Are there any good tutorials out there for someone trying to learn
javascript coming from a python background?

Thanks,

Steven Potter
 
R

RobG

I am new to JavaScript and having a hard time understanding how to
apply OOP principals to JavaScript.

The problem I am running into is that I am binding an event callback
to an instance method, but when that method tries to access an
instance variable, it returns undefined.

I put together a quick example to demonstrate the issue I am having:

OK, I'll treat it as an example. :)

<html>
<head>
</head>
<body>
<a href="#" id="link">Click Here</a></br>

<script type="text/javascript">
function myclass(classattribute){
this.classattrib = classattribute;
this.mymethod = mymethod;
this.mymethod();

That will execute mymethod when myclass is called. Incidentally,
forget all notions of classes, javscript has objects with properties -
that's it.

this.element = document.getElementById('link');
this.element.addEventListener('click', this.mymethod, false);
}

The above appears to be an attempt at a constructor, but I'm not sure
that's what you wanted.

I think you've missed the way the this keyword works in javascript.
Briefly, the this keyword is set by the calling function and is:

1. a reference to the object that the function is called as a method
of or the global (window) object, or

2. set to some other value using the function's call or apply methods,
or

3. set to the new object created when the 'new' operator is used.

function mymethod(){
document.write('Class attribute = '+this.classattrib);

Callling document.write after the page has finished loading will
replace the entire content of the page with the value of the
argument. You first call it during page load, so it will write to the
top of the body element.

If a second call is successful after the page has finished loading, it
will replace your entire page content with whatever it wrote the first
time.

}

testclass = myclass('something');

By calling myclass as a function that way (essentially
window.myclass), its this keyword will be set to the window object.

</script>
</body
</html>

Essentually, the first time mymethod is executed (at page load), it
has no problem accessing this.classattrib,

It creates classattrib as a property of the global object, since that
is what myclass's this keyword references when it is called the first
time.

when it is called again as
a result of the click event, this.classattrib returns undefined.

Because in Firefox, when a function is attached using addEventListener
and subsequently called by the firing of an event, its this keyword is
set as a reference to the element that fired the event (remember that
the call sets the value of the this keyword, you can't change it
later).

In IE, using attachEvent, the function's this keyword would be set to
the global object so your script would "work".

I have tried to read some tutorials, I am finding it all very
confusing because it seems that everything in javascript can be done 3
or 4 different ways.

I don't think javascript is alone in that. :)

Are there any good tutorials out there for someone trying to learn
javascript coming from a python background?

The FAQ (grudgingly) recommends a book, and W3Schools is OK to get
going but be aware that the content it is limited, dated and sometimes
plain wrong. Despite that, it is one of the best on-line resources for
getting started.

clj FAQ:
<URL: http://www.jibbering.com/faq/#FAQ3_1 >

w3schools javascript tutorial:
<URL: http://www.w3schools.com/js/default.asp >
 
S

Steve Potter

Thanks for the response. Below are a few comments and questions.
OK, I'll treat it as an example. :)



That will execute mymethod when myclass is called. Incidentally,
forget all notions of classes, javscript has objects with properties -
that's it.

That is what I intended.
The above appears to be an attempt at a constructor, but I'm not sure
that's what you wanted.

No, not a constructor. I was just looking for some way to demonstrate
the result I had found previously.

I think you've missed the way the this keyword works in javascript.
Briefly, the this keyword is set by the calling function and is:

1. a reference to the object that the function is called as a method
of or the global (window) object, or

2. set to some other value using the function's call or apply methods,
or

3. set to the new object created when the 'new' operator is used.


My understanding of the this keyword was that it is the same as the
self keyword in other languages.

Callling document.write after the page has finished loading will
replace the entire content of the page with the value of the
argument. You first call it during page load, so it will write to the
top of the body element.

If a second call is successful after the page has finished loading, it
will replace your entire page content with whatever it wrote the first
time.

I did consider using the alert. This brings up the issue of trying to
troubleshoot javascript code. I seems very non-intuitive I suppose
because modern browsers go to such extents to hide and correct errors
produced by web pages. I have been making use of FireBug and the
error console in FireFox. Do you have any other recommendations?
By calling myclass as a function that way (essentially
window.myclass), its this keyword will be set to the window object.

I'm sorry, that was a mistake on my part. I had intended to write:
testclass = new myclass('something');
It creates classattrib as a property of the global object, since that
is what myclass's this keyword references when it is called the first
time.


Because in Firefox, when a function is attached using addEventListener
and subsequently called by the firing of an event, its this keyword is
set as a reference to the element that fired the event (remember that
the call sets the value of the this keyword, you can't change it
later).
That is an unintended result. When I bind something to this.method, I
would assume that when that callback is made I would be working with
the same instance of the "this".

In IE, using attachEvent, the function's this keyword would be set to
the global object so your script would "work".

not considering my omission of the "new" above.
I don't think javascript is alone in that. :)

Yes, but it seems that in most languages there becomes a de facto
standard way of doing most things. That doesn't seem to be the case
with javascript.
The FAQ (grudgingly) recommends a book, and W3Schools is OK to get
going but be aware that the content it is limited, dated and sometimes
plain wrong. Despite that, it is one of the best on-line resources for
getting started.

clj FAQ:
<URL:http://www.jibbering.com/faq/#FAQ3_1>

w3schools javascript tutorial:
<URL:http://www.w3schools.com/js/default.asp>

I ran across a book titled "DOM Scripting: Web Design with JavaScript
and the Document Object Model" is anyone familiar with it?


Thanks,

Steven Potter
 
B

Bruno Desthuilliers

Steve Potter a écrit :
Thanks for the response. Below are a few comments and questions. (snip)


My understanding of the this keyword was that it is the same as the
self keyword in other languages.
(snip)
That is an unintended result. When I bind something to this.method, I
would assume that when that callback is made I would be working with
the same instance of the "this".

Well, it's probably one of the biggest javascript gotchas. 'this' is
dynamic.

As far as I'm concerned, I'd recommand Flanagan's book
http://www.oreilly.com/catalog/jscript5/
 
T

Thomas 'PointedEars' Lahn

RobG said:
The above appears to be an attempt at a constructor, but I'm not sure
that's what you wanted.

I think you've missed the way the this keyword works in javascript.
Briefly, the this keyword is set by the calling function and is:

It is set by the *caller* (not by the callee, the called method), which
is a non-function object, unless the method is a called as a method of a
Function object.
Because in Firefox, when a function is attached using addEventListener
and subsequently called by the firing of an event, its this keyword is
set as a reference to the element that fired the event (remember that
the call sets the value of the this keyword, you can't change it
later).

It is not that an element fires an event, but the DOM creates an event
(caused either by user interaction on an [element] object or developer's
API usage) which is then handled by one or more (element) object's event
listeners.


PointedEars
 
R

Richard Cornford

Steve Potter wrote:
My understanding of the this keyword was that it is the
same as the self keyword in other languages.

In many programming languages the - this - or - self -
keywords/operators (or whatever they are called in those languages),
when used inside the code that defines a method, will always refer to an
object instance, where the object instance is an instance of the class
(or sub-class of the class) in which the method is defined. In
javascript the value of the - this - keyword is always determined (and
only determined) by how a function is called, at the point where it is
called. (and that has nothing to do with scope, as scope is determine by
where a function is created)

People who come to javascript from other languages frequency trip over
this aspect of the - this - keyword, but javascript is a language where
bringing in expectations acquired programming other languages is often
disappointing.

That is an unintended result. When I bind something to
this.method,

"Bind" is not a term that has meaning in javascript as a language. It is
a term that is frequently applied to a particular implementation
strategy that is intended to force - this - values in function calls
into being references to particular objects, but that is not what you
have been doing here.

All that is being done in your code is assigning a reference to a
function object to a property of another object. The function object
undergoes no processes as a result of this action, and does not become
aware that it has been assigned as a property of an object (beyond
whatever may be needed internally for automatic garbage collection to
work).
I would assume that when that callback is made I would
be working with the same instance of the "this".

The - this - value will be determined by how the function gets called in
the 'callback'. If you can see how it gets called you can determine what
the - this - reference will be, with certainty, but where you cannot see
you can only observe the results of tests and trust to consistency (or
documentation).
not considering my omission of the "new" above.

But using the - new - operator only determines the - this - value for
the call to the constructor, and so which object the method is assigned
to. It does not change the fact that the function object has no interest
in, or knowledge of, the fact that it has been assigned as a method of
an object.
Yes, but it seems that in most languages there becomes a de facto
standard way of doing most things. That doesn't seem to be the
case with javascript.

It is extremely easy to implement the concepts from class-based
languages in javascript. Being easy it is inevitable that there are many
ways of doing it. However, javascript has characteristics that are
fairly unique and impact heavily on code design decision. Including the
fact that in most contexts of its use it is implementing relatively
small-scale systems and context specific functionality, while being
delivered as source code and interpreted/complied into something
executable just prior to use.

This means that it is a good idea not to be doing more than is necessary
to get the job done in context. So where there is no need for a deep
tree of sub-classes (as is almost always the case in reality) there is
no need to implement the code that would facilitate easy deep
sub-classing, for example. Another concept from class-based languages
that can be implemented is access control (the 'public'/'private' member
notion). You can do it, but 99% of the time there is no point, and code
that implements the concept will run slower (and be bigger) than code
that does not, so where there is no need it becomes a bad idea to try.

The best approach has always been to understand the possibilities for
implementing the concepts from class-based languages in javascript, and
then to use the one that is sufficient, but no more than sufficient, for
the task in hand. The result is that there is no standard approach, just
a set of re-occurring themes, better or worse suited to particular
contexts.

I ran across a book titled "DOM Scripting: Web Design
with JavaScript and the Document Object Model" is
anyone familiar with it?

I am not, but with a title like that (and given that books on javascript
range form the barely acceptable to the positively bad) it sounds
dangerous. Is there an example chapter from the book online somewhere,
and if there is, is it one that has some technical content rather than
introduction/history? (The publishers of bad javascript books prefer not
to put the technical chapters up where people with the knowledge to do
so can judge them).

Richard.
 
S

Steve Potter

In many programming languages the - this - or - self -
keywords/operators (or whatever they are called in those languages),
when used inside the code that defines a method, will always refer to an
object instance, where the object instance is an instance of the class
(or sub-class of the class) in which the method is defined. In
javascript the value of the - this - keyword is always determined (and
only determined) by how a function is called, at the point where it is
called. (and that has nothing to do with scope, as scope is determine by
where a function is created)

People who come to javascript from other languages frequency trip over
this aspect of the - this - keyword, but javascript is a language where
bringing in expectations acquired programming other languages is often
disappointing.

Yes, I stopped by the local B$N today and read the chapter from
"JavaScript: The Definitive Guide" about classes. It explained this
concept quite well.

I guess I will have to re-think the project I was working on.

Is there a decent FAQ somewhere that explains common stumbling blocks?


Thanks,

Steven Potter
 

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
474,156
Messages
2,570,878
Members
47,408
Latest member
AlenaRay88

Latest Threads

Top