473,503 Members | 1,749 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

this confusion

Simplified example code which can be copy/pasted and will exhibit the
problem.

var ob={id:2};
ob.alertid=function(){alert("id="+this.id);}
ob.funcs=[ob.alertid];
ob.testalert=function(){
this.alertid(); //this works
this.funcs[0](); //this doesn't
}

ob.testalert();

I have an object with an id property. The alertid function alerts that
id property if it's called directly, but not if it's called via an array
of function pointers. I don't understand the difference. Why is 'this'
different in those two cases. It's the same object method isn't it.

The output is:

id=2
id=undefined
Aug 8 '07 #1
10 1198
On Aug 9, 7:23 am, Stevo <ple...@spam-me.comwrote:
Simplified example code which can be copy/pasted and will exhibit the
problem.

var ob={id:2};
ob.alertid=function(){alert("id="+this.id);}
ob.funcs=[ob.alertid];
ob.testalert=function(){
this.alertid(); //this works
this.funcs[0](); //this doesn't

}

ob.testalert();

I have an object with an id property. The alertid function alerts that
id property if it's called directly, but not if it's called via an array
of function pointers. I don't understand the difference. Why is 'this'
different in those two cases. It's the same object method isn't it.
I think the best post I've seen about the this keyword is the one here
by Mike Winter:

<URL:
http://groups.google.com.au/group/co...26cd885e01c292
>

The first part is about closures, the second part on this is
excellent.
--
Rob

Aug 8 '07 #2
On Aug 8, 5:23 pm, Stevo <ple...@spam-me.comwrote:
Simplified example code which can be copy/pasted and will exhibit the
problem.

var ob={id:2};
ob.alertid=function(){alert("id="+this.id);}
ob.funcs=[ob.alertid];
ob.testalert=function(){
this.alertid(); //this works
Right. Because you called a method of the ob object. In this case,
"this" is ob, which has an id property.
this.funcs[0](); //this doesn't
funcs[0] holds a reference to an anonymous function. The fact that ob
has a property (alertid method) that references it as well is
meaningless. In this case, "this" refers to the anonymous function,
which has no id property.
Aug 9 '07 #3
David Mark wrote:
In this case, "this" refers to the anonymous function,
which has no id property.
Thanks David, Randy, Thomas and Rob. You all said the same thing
basically, this differs depending on how it's called. Excellent link
Rob, that's one to bookmark.

I've altered the alertid function to add 'that' and it now works.

var ob={id:2};
ob.alertid=function(){var that=ob;alert("id="+that.id);}
ob.funcs=[ob.alertid];
ob.testalert=function(){
this.alertid();
this.funcs[0]();
}
ob.testalert();

That has the name ob hard-coded in the alertid function though. I wonder
if it's possible to create 'that' without knowing the name of the
object? Take the following example with ??? where I don't know what to set:

var ob_a={id:"a"};
var ob_b={id:"b"};
var alertid=function(){var that=???;alert("id="+that.id);}
ob_a.alertid=alertid;
ob_b.alertid=alertid;

I'm guessing that there's no way to define 'that' which would work for
both objects there, and I'd have to define an anonymous function for
each object, with hard-coded references to ob_a and ob_b in them like so:

var ob_a={id:"a"};
var ob_b={id:"b"};
ob_a.alertid=function(){var that=ob_a;alert("id="+that.id);};
ob_b.alertid=function(){var that=ob_b;alert("id="+that.id);}
Aug 9 '07 #4
Stevo wrote:
[...] I wonder if it's possible to create 'that' without knowing the name of the
object? Take the following example with ??? where I don't know what to set:

var ob_a={id:"a"};
var ob_b={id:"b"};
var alertid=function(){var that=???;alert("id="+that.id);}
ob_a.alertid=alertid;
ob_b.alertid=alertid;

I'm guessing that there's no way to define 'that' which would work for
both objects there, and I'd have to define an anonymous function for
each object, with hard-coded references to ob_a and ob_b in them like so:

var ob_a={id:"a"};
var ob_b={id:"b"};
ob_a.alertid=function(){var that=ob_a;alert("id="+that.id);};
ob_b.alertid=function(){var that=ob_b;alert("id="+that.id);}
var alertid = function(that){ alert("id=" + that.id); };
// ...
ob_a.alertid = function() { alertid(this); };
ob_b.alertid = function() { alertid(this); };

or

var alertid = function(){ alert("id=" + this.id); }
// ...

and then either

ob_a.alertid = function() { alertid.call(this); };
ob_b.alertid = function() { alertid.call(this); };

or

ob_a.alertid = function() { alertid.apply(this); };
ob_b.alertid = function() { alertid.apply(this); };
HTH

PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f8*******************@news.demon.co.uk>
Aug 9 '07 #5
Stevo wrote:
[...] I wonder if it's possible to create 'that' without knowing the name of the
object? Take the following example with ??? where I don't know what to set:

var ob_a={id:"a"};
var ob_b={id:"b"};
var alertid=function(){var that=???;alert("id="+that.id);}
ob_a.alertid=alertid;
ob_b.alertid=alertid;

I'm guessing that there's no way to define 'that' which would work for
both objects there, and I'd have to define an anonymous function for
each object, with hard-coded references to ob_a and ob_b in them like so:

var ob_a={id:"a"};
var ob_b={id:"b"};
ob_a.alertid=function(){var that=ob_a;alert("id="+that.id);};
ob_b.alertid=function(){var that=ob_b;alert("id="+that.id);}
var alertid = function(that){ alert("id=" + that.id); };
// ...
ob_a.alertid = function() { alertid(this); };
ob_b.alertid = function() { alertid(this); };

or

var alertid = function(){ alert("id=" + this.id); }
// ...

and then either

ob_a.alertid = function() { alertid.call(this); };
ob_b.alertid = function() { alertid.call(this); };

or

ob_a.alertid = function() { alertid.apply(this); };
ob_b.alertid = function() { alertid.apply(this); };
HTH

PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f8*******************@news.demon.co.uk>
Aug 9 '07 #6
Stevo wrote:
[...] I wonder if it's possible to create 'that' without knowing the name of the
object? Take the following example with ??? where I don't know what to set:

var ob_a={id:"a"};
var ob_b={id:"b"};
var alertid=function(){var that=???;alert("id="+that.id);}
ob_a.alertid=alertid;
ob_b.alertid=alertid;

I'm guessing that there's no way to define 'that' which would work for
both objects there, and I'd have to define an anonymous function for
each object, with hard-coded references to ob_a and ob_b in them like so:

var ob_a={id:"a"};
var ob_b={id:"b"};
ob_a.alertid=function(){var that=ob_a;alert("id="+that.id);};
ob_b.alertid=function(){var that=ob_b;alert("id="+that.id);}
var alertid = function(that){ alert("id=" + that.id); };
// ...
ob_a.alertid = function() { alertid(this); };
ob_b.alertid = function() { alertid(this); };

or

var alertid = function(){ alert("id=" + this.id); }
// ...

and then either

ob_a.alertid = function() { alertid.call(this); };
ob_b.alertid = function() { alertid.call(this); };

or

ob_a.alertid = function() { alertid.apply(this); };
ob_b.alertid = function() { alertid.apply(this); };
HTH

PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f8*******************@news.demon.co.uk>
Aug 9 '07 #7
Stevo wrote:
[...] I wonder if it's possible to create 'that' without knowing the name of the
object? Take the following example with ??? where I don't know what to set:

var ob_a={id:"a"};
var ob_b={id:"b"};
var alertid=function(){var that=???;alert("id="+that.id);}
ob_a.alertid=alertid;
ob_b.alertid=alertid;

I'm guessing that there's no way to define 'that' which would work for
both objects there, and I'd have to define an anonymous function for
each object, with hard-coded references to ob_a and ob_b in them like so:

var ob_a={id:"a"};
var ob_b={id:"b"};
ob_a.alertid=function(){var that=ob_a;alert("id="+that.id);};
ob_b.alertid=function(){var that=ob_b;alert("id="+that.id);}
var alertid = function(that){ alert("id=" + that.id); };
// ...
ob_a.alertid = function() { alertid(this); };
ob_b.alertid = function() { alertid(this); };

or

var alertid = function(){ alert("id=" + this.id); }
// ...

and then either

ob_a.alertid = function() { alertid.call(this); };
ob_b.alertid = function() { alertid.call(this); };

or

ob_a.alertid = function() { alertid.apply(this); };
ob_b.alertid = function() { alertid.apply(this); };
HTH

PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f8*******************@news.demon.co.uk>
Aug 9 '07 #8
Stevo wrote:
[...] I wonder if it's possible to create 'that' without knowing the name of the
object? Take the following example with ??? where I don't know what to set:

var ob_a={id:"a"};
var ob_b={id:"b"};
var alertid=function(){var that=???;alert("id="+that.id);}
ob_a.alertid=alertid;
ob_b.alertid=alertid;

I'm guessing that there's no way to define 'that' which would work for
both objects there, and I'd have to define an anonymous function for
each object, with hard-coded references to ob_a and ob_b in them like so:

var ob_a={id:"a"};
var ob_b={id:"b"};
ob_a.alertid=function(){var that=ob_a;alert("id="+that.id);};
ob_b.alertid=function(){var that=ob_b;alert("id="+that.id);}
var alertid = function(that){ alert("id=" + that.id); };
// ...
ob_a.alertid = function() { alertid(this); };
ob_b.alertid = function() { alertid(this); };

or

var alertid = function(){ alert("id=" + this.id); }
// ...

and then either

ob_a.alertid = function() { alertid.call(this); };
ob_b.alertid = function() { alertid.call(this); };

or

ob_a.alertid = function() { alertid.apply(this); };
ob_b.alertid = function() { alertid.apply(this); };
HTH

PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f8*******************@news.demon.co.uk>
Aug 9 '07 #9
On Aug 16, 3:50 pm, ron.h.h...@gmail.com wrote:
<snip>
In other words, a function invoked as f(...) will have a
"this" value of the global object,
function f(){
var x = (this+'');
}

with(
{
f:f,
toString:function(){alert('I am not the global object');}
}
){
f(); // alerts: I am not the global object
// So the - this - value when - f() - is
// executed is _not_ the global object.
}

You appear to have failed to take into account the role of variable
objects and the scope chain in determining the - this - value.

<snip>
So the second problem with Mike's post is that it over-complicates
the description of what one should expect of the "this" value to
be by involving the variable object, scope chain and the "new"
operator[1] in the description.
<snip>

Aug 16 '07 #10
On Aug 17, 12:50 am, ron.h.h...@gmail.com wrote:
On Aug 8, 4:17 pm, RobG <rg...@iinet.net.auwrote:
On Aug 9, 7:23 am, Stevo <ple...@spam-me.comwrote:

<..>
I think the best post I've seen about the this keyword is the one here
by Mike Winter:
<URL:http://groups.google.com.au/group/co...browse_frm/thr...
The first part is about closures, the second part on this is
excellent.

With regard to the second part only, and in spite of many excellent
posts that Mike contributed, this one doesn't quite make that rating
in my book.

The first problem is the use of the term "this operator" which,
Mike explained in another post why he uses that term. I've spent some
time trying to find it but can't.

[...]
If the reference to the method is obtained without use of dot or
bracket notation, "this" is assigned a reference to the global object.
On the other hand if dot or bracket notation is used to arrive at the
reference, "this" is assigned the object at the end of the accessor
path that leads to the reference.

In other words, a function invoked as f(...) will have a "this" value
of the global object, whereas a.b.c.f(...) would have a "this" value
of c.

Perhaps most non-intuitive in the above is that the above paragraph
applies even when an inner function is called, where one might expect
the "this" value to be preserved (as it is when code under the eval
function is invoked).

So the second problem with Mike's post is that it over-complicates the
description of what one should expect of the "this" value to be by
involving the variable object, scope chain and the "new" operator[1]
in the description.
I think he's being thorough. His explanation regarding identifier
resolution explains how the this keyword of an inner function is a
reference to the global object, even if the this keyword of the outer
function is some other value.

e.g.

function foo(){
alert('foo: this == window : ' + !!(this == window));
function bar() {
alert('bar: this == window : ' + !!(this == window));
}
bar();
}
var x = {};
x.foo = foo;
x.foo(); // foo: this == window : false
// bar: this == window : true
When resolving the local variable bar, it is found on foo's variable
object and so its this keyword is set to the global object, even
though the outer function, foo, has its this keyword set to x.

If a programmer wants the inner function to have access to the outer
function's this keyword, they can do:

function foo(){
var fooThis = this;
function bar() {
// Use fooThis
}
bar();
}

or

function foo(){
function bar() {
// this = foo's this;
}
bar.call(this);
}

>
See "Objects and this" at

<URL:http://javascript.crockford.com/survey.html>

for a much more succinct, easy to grasp, description.
It is a simple description that covers the majority of cases, but it
doesn't explain why. One reason I like Mike's explanations is that
they can be read and understood in conjunction with the ECMAScript
specification [1]. I don't think Douglas Crockford's can (which isn't
a criticism, I suspect that was never his intention).
1. Richard Cornford's posts fall into the same category, though they
are often much more difficult to understand.

--
Rob

Aug 17 '07 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
1986
by: Mathias Mamsch | last post by:
Hi, I have some confusion concerning the weakref module. I am trying to save a weak reference to a bound member function of a class instance for using it as a callback function. But I always...
10
1922
by: Kamilche | last post by:
I'm trying to pack two characters into a single byte, and the shifting in Python has me confused. Essentially, it should be possible to use a 'packed string' format in Python, where as long as...
3
1844
by: Simon Johnson | last post by:
I'm trying to create an RSS 2.0 compliant feed but I'm meeting some confusion over the pubDate element. It clearly states next to the pubDate that the date should be formatted in compliance...
8
1425
by: Martin Gieseking | last post by:
Hello I've the following piece of code that compiles fine: typedef int (*(*T)); T *t = new T; Now I would like to avoid the typedef but don't really know how to do this. Is it possible at...
8
3314
by: gg | last post by:
I am confused regarding what the line in the following function does. It seems to work ok. It seems to be creating a new T object using the pointer to an existing T object. But which function is it...
4
2531
by: JMCN | last post by:
object invalid or no longer set - confusion of the recordset in access 2003. i am currently converting from access 97 to access 2003. majority of the codes converted over perfectly fine, though...
4
1501
by: FDude | last post by:
Hello folks: I am just starting to delve into the DUMPS from the ILDASM utility. Can I do anything useful with the outputted IL code? Can someone give me some references to working with .IL...
5
1276
by: Peter Oliphant | last post by:
I was thinking it might be a good idea to split this newsgroup into different newsgroups, depending on the version of VS C++.NET being discussed. Thus, there would be 2002, 2003, and 2005...
14
1393
by: bbawa1 | last post by:
It says invalid expression term && protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) { if...
40
1949
by: Dave | last post by:
Hello, I'm teaching myself C by working my way through Steve Summit's tutorial (http://www.eskimo.com/~scs/cclass/cclass.html). In one of the questions (assignment 6, exercise 7), you have to...
0
7202
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7280
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
5578
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5014
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4672
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3167
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3154
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1512
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
380
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.