By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,660 Members | 1,939 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,660 IT Pros & Developers. It's quick & easy.

How to understand the javascript class model?

P: n/a
hi every one,

I have got some confused problem when I try to write some custom object
by javascript.

Look at the example code here:

<BODY>
<script language="jscript">

function Class()
{

this.member = null;
this.event = null;

this.memberFunction = function()
{
alert("memberfunc" + this.member);
this.callEvent();
alert('after call');
}

this.callEvent = function()
{
alert("call:" + this.event);
if (this.event)
{
this.event();
}
}

}

var obj = new Class();
obj.member = "hello";

obj.event = function()
{
alert('event');
}

obj.memberFunction();
</script>

<button id=hello >click</button>
<script>
hello.onclick=obj.memberFunction;
</script>

I try to define a javascript class and define a event handler for it.
There is a member and
a memberFunction and a event in the Class body. Then I created a object
(obj) of Class and
defined a event handler like this:

obj.event = function()
{
alert('event');
}

When I call the function: obj.memberFunction(); the event handler was
fired and alert
a message ('event'). But when I try to use a button to fire the event, it
doesn't work. It seems we
have lost the member function callEvent, it is a undefined value, the same
as this.event member.

Anyone can tell me why?

Aug 25 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
On 25/08/2005 03:15, Jing You wrote:
<script language="jscript">
The language attribute has long-been deprecated in favour of the
(required) type attribute:

<script type="text/javascript">
function Class()
{

this.member = null;
this.event = null;

this.memberFunction = function()
{
alert("memberfunc" + this.member);
this.callEvent();
alert('after call');
}

this.callEvent = function()
{
alert("call:" + this.event);
if (this.event)
{
this.event();
}
}

}
In general, when all data members 'public', methods should be added via
the prototype object. This produces only one function object for each
method. With the code above, each new object will create new functions
even though they could be shared.

function Class() {
this.member = null;
this.event = null;
}
Class.prototype.memberFunction = function() {
alert('memberFunction: ' + this.member);
this.callEvent();
alert('after call');
};
Class.prototype.callEvent = function() {
alert('callEvent: ' + this.event);
if('function' == typeof this.event) {this.event();}
};

Creating methods as you did should normally be used when utilising
'private' members:

function MyObject() {
var private = 'value';

this.method = function() {
alert(private);
};
}

var o = new MyObject();

o.method(); // 'value'
o.private; // error

[snip]
<button id=hello >click</button>
<script>
hello.onclick=obj.memberFunction;
</script>
The value of id and name attributes should never be used as global
variables. Many browsers do not support this.

var element;

if(document.getElementById) {
element = document.getElementById('hello');
}
if(element) {
element.onclick = obj.memberFunction;
}
I try to define a javascript class [...]
There's no such thing. Javascript uses a prototype-based inheritance
model, where your objects use other objects as a basis for their
features and behaviours. Your Class, above, is a constructor function
that when executed, can be used to initialise an object instance and
augment the object that results from the instantiation.
When I call the function: obj.memberFunction(); the event handler was
fired and alert a message ('event'). But when I try to use a button
to fire the event, it doesn't work.


The this operator exists everywhere (unlike in other languages), and as
such, its value is determined by how code is executed.

In 'global' scope

<script type="text/javascript">
alert(this == window); // true
</script>

the this operator refers to the global object (usually referred to as
window). Similarly, functions that are called directly have the same value:

var o = {
method : function() {alert(this == window);}
},
f = o.method;

f(); // true; this refers to global object
o.method(); // false; same function object,
// but this now refers to 'o'

Notice that in this latter case, the this operator refers to the object
before the last dot operator: 'o'. A similar thing happens in your case.
When the browser fires the event listener, it does so as though it did

buttonElement.onclick()

In other words, the this operator refers to the BUTTON element.

To solve this, you need to keep a reference to the object that you can
use later. One way is to use the 'private' member form I showed earlier:

function Class() {
var instance = this;

this.member = null;
this.event = null;

this.memberFunction = function() {
alert('memberFunction: ' + instance.member);
instance.callEvent();
alert('after call');
};
}
Class.prototype.callEvent = function() {
alert('callEvent: ' + this.event);
if('function' == typeof this.event) {this.event();}
};

Looking at the implementation of the memberFunction member, you can see
that it's defined in terms of the instance private variable. Even when
the this operator will refer to the BUTTON element, instance will still
refer to the object. When the method calls the callEvent method, it does
so through the object reference, so the this operator will refer to the
object again.

Hope that helps,
Mike

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
Aug 25 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.