Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

'this' confusion

5 views
Skip to first unread message

robean

unread,
Mar 19, 2009, 3:13:03 PM3/19/09
to
Newbie question:

Here is some code from the Rhino book:

var calculator = {
operator1: 1,
operator2: 1,
compute: function() {
this.result = this.op1 + this.op2;
}
};

calculator.compute();
alert(calculator.result);


The use of 'this' in the above example is pretty clear, but what would
be the downside of referencing the calling object using the object
name, rather than using 'this'? So, change

this.result = this.op1 + this.op2;
to
calculator.result = calculator.op1 + calculator.op2;


I ask because javascript's confusing implementation of 'this' is a
source of much grief (with 'this' refering to the global object in
some contexts, etc.) : using the object name explicitly instead of
using 'this' could help matters sometimes. But, is there a downside
to this?

ST

Thomas 'PointedEars' Lahn

unread,
Mar 19, 2009, 3:22:53 PM3/19/09
to
robean wrote:
> Newbie question:
>
> Here is some code from the Rhino book:
>
> var calculator = {
> operator1: 1,
> operator2: 1,
> compute: function() {
> this.result = this.op1 + this.op2;
> }
> };
>
> calculator.compute();
> alert(calculator.result);
>
>
> The use of 'this' in the above example is pretty clear, but what would
> be the downside of referencing the calling object using the object
> name, rather than using 'this'?

Another closure, and unnecessary repetition of an identifier in source code.

The closure would prevent the method from being reused, and circular
references involving host objects from being garbage collected in MSHTML.

Unnecessary repetition makes maintenance harder than it needs to be.

> [...]


> I ask because javascript's confusing implementation of 'this' is a
> source of much grief (with 'this' refering to the global object in
> some contexts, etc.) :

On the contrary, what `this' would refer to is quite easy to determine if
you imagine the context in which it occurs to be entered. Because, as in
other programming languages supporting this mechanism, it is the caller that
determines the `this' value. And in ECMAScript implementations, where there
is no caller (or the caller is the Global Object), `this' refers to the
Global Object.

> using the object name explicitly instead of using 'this' could help
> matters sometimes.

Only to the uninitiated.


PointedEars

robean

unread,
Mar 19, 2009, 3:36:36 PM3/19/09
to
On Mar 19, 12:22 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:

Many thanks.

- Robean (uninitiated++)

Matt Kruse

unread,
Mar 19, 2009, 4:26:05 PM3/19/09
to
On Mar 19, 2:22 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:

> > The use of 'this' in the above example is pretty clear, but what would
> > be the downside of referencing the calling object using the object
> > name, rather than using 'this'?
> The closure would prevent the method from being reused, and circular
> references involving host objects from being garbage collected in MSHTML.

I don't see any references to DOM objects in the code, so I don't
think the circular reference would matter for garbage collection.

How would the closure prevent the method from being reused? Perhaps
something like this:
mycalc2.compute = calculator.compute;
would be a problem (mycalc2.compute() would not operate on the mycalc2
object) but it could also be an advantage.

If somewhere else in the code you wanted to keep a reference to
calculator.compute such as:

var f = calculator.compute;
...
f();

This would work if 'calculator' were explicitly used in the method,
but would not work if 'this' were used.

I've had situations where I wanted to pass around references to object
methods and call them without the object qualifier, and I found that
explicitly referencing the object within the methods was an easy
solution. Of course there are other options, but it works.

> Unnecessary repetition makes maintenance harder than it needs to be.

Help Stamp Out & Eradicate Superfluous Redundancy!

Matt Kruse

Jon Gómez

unread,
Mar 19, 2009, 5:18:37 PM3/19/09
to
Thomas 'PointedEars' Lahn wrote:
> robean wrote:
>> Newbie question:
>>
>> Here is some code from the Rhino book:
>>
>> var calculator = {
>> operator1: 1,
>> operator2: 1,
>> compute: function() {
>> this.result = this.op1 + this.op2;
>> }
>> };
>>
>> calculator.compute();
>> alert(calculator.result);
>>
>>
>> The use of 'this' in the above example is pretty clear, but what would
>> be the downside of referencing the calling object using the object
>> name, rather than using 'this'?
>
> Another closure, and unnecessary repetition of an identifier in source code.
[...]

The way the OP specified the usage of calculator inside the function,
there wasn't any variable declaration for 'calculator', so wouldn't the
engine merely go up the [[Scope]] chain looking for the property named
'calculator', and finally find it on the global object? In no way is it
actually becoming attached to any real implementation analogy of an
"activation object" for the function, right? How is a circular
reference possible? How is it supposed to persist in the closure of the
function?

Jon.

Jorge

unread,
Mar 19, 2009, 6:13:51 PM3/19/09
to
On Mar 19, 8:13 pm, robean <st1...@gmail.com> wrote:
> (...)

>
> The use of 'this' in the above example is pretty clear, but what would
> be the downside of referencing the calling object using the object
> name, rather than using 'this'?  So, change
>
>             this.result = this.op1 + this.op2;
> to
>             calculator.result = calculator.op1 + calculator.op2;
>
> I ask because javascript's confusing implementation of 'this' is a
> source of much grief (with 'this' refering to the global object in
> some contexts, etc.) : using the object name explicitly instead of
> using 'this' could  help matters sometimes. But, is there a downside
> to this?

There's a downside: "this" is a must to achieve code reuse in
(inheritable) public methods (usually attached to objects acting as
prototypes). Otoh, in an instance's own public methods there's no need
to rely on "this" and in many cases it may even be better not to and,
instead, refer explicitly to the instance.

--
Jorge.

RobG

unread,
Mar 19, 2009, 6:42:23 PM3/19/09
to
On Mar 20, 5:22 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:

> robean wrote:
> > Newbie question:
>
> > Here is some code from the Rhino book:
>
> > var calculator = {
> > operator1: 1,
> > operator2: 1,
> > compute: function() {
> > this.result = this.op1 + this.op2;
> > }
> > };
>
> > calculator.compute();
> > alert(calculator.result);
>
> > The use of 'this' in the above example is pretty clear, but what would
> > be the downside of referencing the calling object using the object
> > name, rather than using 'this'?
>
> Another closure, and unnecessary repetition of an identifier in source code.

Surely there is only one closure, the one formed by the function
expression? That closure is formed regardless of which pattern is
used, and since it's global code, the closure is formed with the
global object, which would be on the scope chain anyway. Where is the
downside of that?


> The closure would prevent the method from being reused,

That depends on the context, it certainly changes how the function
behaves.


> and circular
> references involving host objects from being garbage collected in MSHTML.

If you're talking generally about the pattern, yes, but there is no
inference of that occurring here.

Didn't MS fix that issue with IE 7?


[...]


> > using the object name explicitly instead of using 'this' could help
> > matters sometimes.

Yes, it can.


> Only to the uninitiated.

And to others, it should be addressed on a case-by-case basis.


--
Rob

Jon Gómez

unread,
Mar 19, 2009, 6:44:02 PM3/19/09
to
Thomas 'PointedEars' Lahn wrote:
> On the contrary, what `this' would refer to is quite easy to determine if
> you imagine the context in which it occurs to be entered. Because, as in
> other programming languages supporting this mechanism, it is the caller that
> determines the `this' value. And in ECMAScript implementations, where there
> is no caller (or the caller is the Global Object), `this' refers to the
> Global Object.

A good thing to bear in mind while programming Javascript.

Even with the explanation, it is a little disturbing to the uninitiated
as you call us that these are all different:
setInterval(obj.func, 1000)
setInterval("obj.func", 1000)
setInterval("obj.func()", 1000)
setInterval(obj.func(), 1000)

I think most of why it makes sense in Javascript for me, and it is just
my opinion, is the consistency it gives to the idea of the function as
an object assigned as a value of a property.

In a language with classes, it may be reasonable for function objects to
be tied to the object they are defined on. Not saying it has to be one
way or the other, though, just that there is a rationale in that the
function can be considered more closely linked to the object because of
the class definition.

Since you brought up the comparison of languages, I thought I'd throw in
a possible counter-example. I feel the language Ruby, in at least one
context, acts as I suggested. One can grab methods from objects using
Object.method, which remain associated with the originating object:

"Method objects are created by Object#method, and are associated with a
particular object (not just with a class). They may be used to invoke
the method within the object, and as a block associated with an
iterator." -- Programming Ruby (Hunt and Thomas)

On the other hand, there are proc objects which are not directly bound
to an originating object (but to closures...).

Jon.

Thomas 'PointedEars' Lahn

unread,
Mar 19, 2009, 6:52:42 PM3/19/09
to
Matt Kruse wrote:

> Thomas 'PointedEars' Lahn wrote:
>>> The use of 'this' in the above example is pretty clear, but what would
>>> be the downside of referencing the calling object using the object
>>> name, rather than using 'this'?
>> The closure would prevent the method from being reused, and circular
>> references involving host objects from being garbage collected in MSHTML.
>
> I don't see any references to DOM objects in the code, so I don't
> think the circular reference would matter for garbage collection.

Not in *this* code.

> How would the closure prevent the method from being reused?

That should be obvious. In any case, reuse would be made at least harder.

> Perhaps something like this:
> mycalc2.compute = calculator.compute;
> would be a problem (mycalc2.compute() would not operate on the mycalc2
> object) but it could also be an advantage.

And if my grandmother had wheels, she'd be a bandwagon. The OP asked for
possible downsides and I provided exactly that.

> [...]

>> Unnecessary repetition makes maintenance harder than it needs to be.
>
> Help Stamp Out & Eradicate Superfluous Redundancy!

I don't follow.


PointedEars

Thomas 'PointedEars' Lahn

unread,
Mar 19, 2009, 7:09:03 PM3/19/09
to
RobG wrote:

> Thomas 'PointedEars' Lahn wrote:
>> robean wrote:
>>> Newbie question:
>>> Here is some code from the Rhino book:
>>> var calculator = {
>>> operator1: 1,
^^^^^^^^^
>>> operator2: 1,
^^^^^^^^^

>>> compute: function() {
>>> this.result = this.op1 + this.op2;
^^^ ^^^
>>> }
>>> };
>>> calculator.compute();
>>> alert(calculator.result);

undefined + undefined == NaN

>>> The use of 'this' in the above example is pretty clear,

The intended use perhaps.

>>> but what would be the downside of referencing the calling object using
>>> the object name, rather than using 'this'?
>> Another closure, and unnecessary repetition of an identifier in source code.
>

> Surely there is only one closure, the one formed by the functionnnn
> expression?

In this code I see no closure. However, if `this' would be replaced with
`calculator', which is what the OP was asking about, there would be a
closure through the function expression, and `calculator' was its bound
variable, literally.

> That closure is formed regardless of which pattern is used,

Where is that closure here?

> and since it's global code, the closure is formed with the
> global object, which would be on the scope chain anyway.

That is _not_ a closure. Where is the required bound variable to occur in
the source code of the function?

> Where is the downside of that?

Suppose `this' was replaced with `calculator' above (as the OP suggested),
and `operator1' was supposed to be `op1', and `operator2' was supposed to be
`op2' (else the example would make little sense), the following could happen:

function Calculator() {}

Calculator.prototype = calculator;
var c = new Calculator();
c.op1 = 42;
c.op2 = 23;

// 2
c.compute();

BTW, OP, the syntax of addition is: operand(summand) operator(+)
operand(summand).

>> The closure would prevent the method from being reused,
>
> That depends on the context, it certainly changes how the function
> behaves.

I have answered the question. Some of us seem to have read a different
question, something along "What would be the advantages of keeping it like
that?"

> [snipped further irrelevance]


> Didn't MS fix that issue with IE 7?

AFAIK we are still testing.


PointedEars

kangax

unread,
Mar 19, 2009, 9:06:16 PM3/19/09
to
Thomas 'PointedEars' Lahn wrote:
> RobG wrote:
[...]

>> and since it's global code, the closure is formed with the
>> global object, which would be on the scope chain anyway.
>
> That is _not_ a closure. Where is the required bound variable to occur in
> the source code of the function?

How does variable occurrence affect closure forming? When a function is
defined (by a function expression) its [[Scope]] is set in such way that
it includes the scope of the calling context, and that calling context's
scope has `constructor` variable. As I understand it, the closure is
formed anyway; the presence of Identifier in a function body should not
affect closure creation. I suppose it could only affect some internal
engine optimizations (and only in cases when engine can guarantee that
no dynamic evaluation will take place, and so an identifier in question
would never need to be resolved; e.g. - `eval('constru' + 'ctor')`).

Am I missing something?

>
>> Where is the downside of that?
>
> Suppose `this' was replaced with `calculator' above (as the OP suggested),
> and `operator1' was supposed to be `op1', and `operator2' was supposed to be
> `op2' (else the example would make little sense), the following could happen:
>
> function Calculator() {}
>
> Calculator.prototype = calculator;
> var c = new Calculator();
> c.op1 = 42;
> c.op2 = 23;
>
> // 2
> c.compute();

Yes. In other words, the code becomes less portable.

[...]

--
kangax

RobG

unread,
Mar 19, 2009, 9:30:14 PM3/19/09
to
On Mar 20, 9:09 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:

> RobG wrote:
> > Thomas 'PointedEars' Lahn wrote:
> >> robean wrote:
> >>> Newbie question:
> >>> Here is some code from the Rhino book:
> >>> var calculator = {
> >>> operator1: 1,
>
> ^^^^^^^^^>>> operator2: 1,
>
> ^^^^^^^^^>>> compute: function() {
> >>> this.result = this.op1 + this.op2;
>
> ^^^ ^^^

Yes, a typo.

>
> >>> }
> >>> };
> >>> calculator.compute();
> >>> alert(calculator.result);
>
> undefined + undefined == NaN

But the intention is clear enough.

[...]


>
> >>> but what would be the downside of referencing the calling object using
> >>> the object name, rather than using 'this'?
> >> Another closure, and unnecessary repetition of an identifier in source code.
>
> > Surely there is only one closure, the one formed by the function

> > expression?
>
> In this code I see no closure. However, if `this' would be replaced with
> `calculator', which is what the OP was asking about, there would be a
> closure through the function expression, and `calculator' was its bound
> variable, literally.

I was under the impression that a closure is formed by creating a
function inside some containing scope (usually another function) - the
function's activation object is placed in the inner function's scope
chain. There is no need to actually reference some "outer" variable
from inside the closure.

As I see it, the calculator object is created by a simple assignment,
the "outer" scope for the compute function is the global scope.
Therefore any closure is formed with the global object, which would be


on the scope chain anyway.

If you are saying that isn't a closure, why bring it up as a
potential downside?

>
> > That closure is formed regardless of which pattern is used,
>
> Where is that closure here?

If one pattern doesn't form a closure, nor does the other.


> > and since it's global code, the closure is formed with the
> > global object, which would be on the scope chain anyway.
>
> That is _not_ a closure. Where is the required bound variable to occur in
> the source code of the function?

There doesn't need to be a bound variable (as explained above). If no
variables are "bound", it becomes (probably) a useless closure, but
it's still there. Consider the classic IE leak:

function foo(id) {
var el = document.getElementById(id);
el.onclick = function(){};
}

The closure and circular reference occurs even though the function
assigned to the onclick property doesn't have any variables that
reference one of foo's variables. For the OP's benefit, the circular
reference is easily fixed by removing it after the assignment to
el.onclick, e.g.

el = null;

or whatever gets rid of the reference to the DOM object before the
function finishes.

> > Where is the downside of that?
>
> Suppose `this' was replaced with `calculator' above (as the OP suggested),
> and `operator1' was supposed to be `op1', and `operator2' was supposed to be
> `op2' (else the example would make little sense), the following could happen:
>
> function Calculator() {}
>
> Calculator.prototype = calculator;
> var c = new Calculator();
> c.op1 = 42;
> c.op2 = 23;
>
> // 2
> c.compute();

Yes, I think a number of responses have pointed that out, but I was
referring to your comment about the closure. The identifier
calculator within the result function is resolved as a property of the
global object, not as a property of some intermediate object created
by a closure.


[...]


> I have answered the question. Some of us seem to have read a different
> question, something along "What would be the advantages of keeping it like
> that?"

No, I was responding to your assertion that "another closure" was a
downside.


> > [snipped further irrelevance]

Lucky it was snipped then!


--
Rob

John G Harris

unread,
Mar 20, 2009, 2:11:48 PM3/20/09
to

But there's still a problem. If you don't use 'this' and do

var a = calculator;
calculator = null;
a.compute();
alert(a.result);

it's not going to work.

Therefore, not using 'this' is a Very Bad Thing unless you're Very Very
Careful.

John
--
John Harris

Jorge

unread,
Mar 20, 2009, 4:10:00 PM3/20/09
to

Put a drop of Loctite :-)

someObject.compute= (function (someObject) {
return function () {
return someObject.result= someObject.this+ someObject.that;
};
})(someObject);

var a = someObject;
someObject = null;
a.compute();
alert(a.result);

--
Jorge.

John G Harris

unread,
Mar 20, 2009, 5:05:47 PM3/20/09
to

What a nasty piece of code.

John
--
John Harris

Jorge

unread,
Mar 20, 2009, 5:55:11 PM3/20/09
to

Lovely, pretty and cool piece of code. Yeah.

--
Jorge.

Thomas 'PointedEars' Lahn

unread,
Mar 20, 2009, 7:15:20 PM3/20/09
to
kangax wrote:
> Thomas 'PointedEars' Lahn wrote:
>> RobG wrote:
> [...]
>>> and since it's global code, the closure is formed with the global
>>> object, which would be on the scope chain anyway.
>> That is _not_ a closure. Where is the required bound variable to occur
>> in the source code of the function?
>
> How does variable occurrence affect closure forming?

It is the sufficient criterion for a closure.

> When a function is defined (by a function expression) its [[Scope]] is
> set in such way that it includes the scope of the calling context, and
> that calling context's scope has `constructor` variable.

First of all, `constructor' is _not_ a variable; not as understood in the
ECMAScript Language Specification, and not as understood in the closure
definition. Secondly, the calling context's scope does _not_ have such a
property.

The object that is the caller of the function may have that property,
however since that property is never referred within the function when it is
defined, there is no closure:

Identifier resolution *along the scope chain* takes place when the function
is executed, not when it is created. But the property of a closure is that
it reproduces the execution context present when and in which it was defined
when it is called (necessary), because there is some *explicit* reference in
the subroutine to an identifier or name that is lexically defined outside of
that subroutine (sufficient).

<http://en.wikipedia.org/wiki/Closure_(computer_science)>

>>> Where is the downside of that?
>> Suppose `this' was replaced with `calculator' above (as the OP
>> suggested), and `operator1' was supposed to be `op1', and `operator2'
>> was supposed to be `op2' (else the example would make little sense),
>> the following could happen:
>>
>> function Calculator() {}
>>
>> Calculator.prototype = calculator;
>> var c = new Calculator();
>> c.op1 = 42;
>> c.op2 = 23;
>>
>> // 2 c.compute();
>
> Yes. In other words, the code becomes less portable.

AFAIK portable usually means "designed in a way so that it can run in a
different environment (e.g. a different hardware platform)". ISTM you mean
"less reusable" instead.


PointedEars

Thomas 'PointedEars' Lahn

unread,
Mar 20, 2009, 7:57:35 PM3/20/09
to
RobG wrote:
> Thomas 'PointedEars' Lahn wrote:
>> RobG wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> robean wrote:
>>>>> Newbie question:
>>>>> Here is some code from the Rhino book:
>>>>> var calculator = {
>>>>> operator1: 1,
>> ^^^^^^^^^>>> operator2: 1,
>>
>> ^^^^^^^^^>>> compute: function() {
>>>>> this.result = this.op1 + this.op2;
>> ^^^ ^^^
>
> Yes, a typo.

Hopefully.

>>>>> }
>>>>> };
>>>>> calculator.compute();
>>>>> alert(calculator.result);
>> undefined + undefined == NaN
>
> But the intention is clear enough.

Nevertheless, the example is seriously flawed (unless its purpose is to
demonstrate how not to do things, or to ask for a solution). Suppose it was
not homework, and was copy-paste and not a typo, how good can a book with
such examples be? That needed to be pointed out.

> [...]
>>>>> but what would be the downside of referencing the calling object using
>>>>> the object name, rather than using 'this'?
>>>> Another closure, and unnecessary repetition of an identifier in source code.
>>> Surely there is only one closure, the one formed by the function
>>> expression?
>> In this code I see no closure. However, if `this' would be replaced with
>> `calculator', which is what the OP was asking about, there would be a
>> closure through the function expression, and `calculator' was its bound
>> variable, literally.
>
> I was under the impression that a closure is formed by creating a
> function inside some containing scope (usually another function) - the
> function's activation object is placed in the inner function's scope
> chain. There is no need to actually reference some "outer" variable
> from inside the closure.

ISTM that is a common misconception, as the Wikipedia article mentions it.

> [...]


> If you are saying that isn't a closure, why bring it up as a
> potential downside?

There is no closure *now*. If `this' was replaced with the identifier of
the variable that a reference to the object that has the function as method
is assigned to, there would be one.

>>> That closure is formed regardless of which pattern is used,
>> Where is that closure here?
>
> If one pattern doesn't form a closure, nor does the other.

Non sequitur.

>>> and since it's global code, the closure is formed with the
>>> global object, which would be on the scope chain anyway.
>> That is _not_ a closure. Where is the required bound variable to occur in
>> the source code of the function?
>
> There doesn't need to be a bound variable (as explained above).

Yes, there does.

> If no variables are "bound", it becomes (probably) a useless closure, but
> it's still there. Consider the classic IE leak:
>
> function foo(id) {
> var el = document.getElementById(id);
> el.onclick = function(){};
> }
>
> The closure and circular reference occurs even though the function
> assigned to the onclick property doesn't have any variables that
> reference one of foo's variables.

There may be a circular reference, but there certainly is no closure here.

>>> [snipped further irrelevance]
>
> Lucky it was snipped then!

Well, it would have been better had it not been in need of being snipped.


PointedEars

kangax

unread,
Mar 21, 2009, 2:43:32 AM3/21/09
to
Thomas 'PointedEars' Lahn wrote:
> kangax wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> RobG wrote:
>> [...]
>>>> and since it's global code, the closure is formed with the global
>>>> object, which would be on the scope chain anyway.
>>> That is _not_ a closure. Where is the required bound variable to occur
>>> in the source code of the function?
>> How does variable occurrence affect closure forming?
>
> It is the sufficient criterion for a closure.

So to make sure I understand this properly:

// No closure is formed
var foo;
function bar(){};

// Closure is formed
var foo;
function bar(){
return foo;
}

What if Identifier is not present?

var fn = (function(){
var x = 5;
return (function(){
return eval(String.fromCharCode(120));
})
})();

I was under impression that returned function object (referred to by
`fn` here) forms a closure during its evaluation as a function
expression; that this closure includes calling context scope - context
of an outer self-executing function - and that this scope has `x` as a
property of its Activation/Variable object and so can be resolved from
within returned `fn`:

fn(); // 5

What did I miss this time?

>
>> When a function is defined (by a function expression) its [[Scope]] is
>> set in such way that it includes the scope of the calling context, and
>> that calling context's scope has `constructor` variable.
>
> First of all, `constructor' is _not_ a variable; not as understood in the
> ECMAScript Language Specification, and not as understood in the closure
> definition. Secondly, the calling context's scope does _not_ have such a
> property.

Ugh... That was supposed to be `calculator`, of course.

>
> The object that is the caller of the function may have that property,
> however since that property is never referred within the function when it is
> defined, there is no closure:
>
> Identifier resolution *along the scope chain* takes place when the function
> is executed, not when it is created. But the property of a closure is that
> it reproduces the execution context present when and in which it was defined
> when it is called (necessary), because there is some *explicit* reference in
> the subroutine to an identifier or name that is lexically defined outside of
> that subroutine (sufficient).

I don't see any mention of explicit references in wikipedia article. I
also can't remember ECMA-262 3rd Ed. specifying anything like that. It
seems that ECMA scope forming mechanism speaks for itself - "scope
objects" include *all* local variables (as properties of "captured"
Activation/Variable object) and those scope objects are then chained
together properly, as function objects are created and their [[Scope]]'s
are being set. There's no discrimination against functions whose bodies
do not contain explicit references, is there?

Can you elaborate, because it seems that me and RobG have very similar
theory (misconception?) in mind.

[...]

>>> // 2 c.compute();
>> Yes. In other words, the code becomes less portable.
>
> AFAIK portable usually means "designed in a way so that it can run in a
> different environment (e.g. a different hardware platform)". ISTM you mean
> "less reusable" instead.

Yep, "less reusable" is a better way to say it.

--
kangax

RobG

unread,
Mar 21, 2009, 2:58:35 AM3/21/09
to
On Mar 21, 9:57 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
> RobG wrote:
[...]

> > I was under the impression that a closure is formed by creating a
> > function inside some containing scope (usually another function) - the
> > function's activation object is placed in the inner function's scope
> > chain. There is no need to actually reference some "outer" variable
> > from inside the closure.
>
> ISTM that is a common misconception, as the Wikipedia article mentions it.

i didn't read it there, I haven't visited the Wikipedia article for
some time.

My opinion was formed initially from a Douglas Crockford post to clj
(I can't find the thread but I'll keep looking, he seems to have
created a number of different accounts, or someone has been
impersonating him). Richard Cornford's "Javascript Closures" article
on the FAQ[1] seems to confirm it, neither the text or examples
indicate the inner function must have references to variables in the
outer scope.


[...]


> > There doesn't need to be a bound variable (as explained above).
>
> Yes, there does.

Very difficult to prove that an inner function with no references to
variables in the outer function creates a closure, but I think I can
exploit IE's memory leak for a useful purpose (it's an ill wind that
blows nobody good). I posted the code below[2] a couple of years ago:

function doLoad() {
for (var i=10000;i--;) {
var p = document.createElement("p");
var x = document.getElementById('xx').innerHTML;
p.appendChild(document.createTextNode("clickme"));
p.onclick =
(function(p, x){return function(){alert("hi");};})(p, x);
document.body.appendChild(p);
document.body.removeChild(p);
}
}

Where xx was a div with about 30k of ipsum lorem. The inner function
(with the alert) is attached as the listener, it has no references to
outer variables, yet it displays IE's memory leak. It must form a
clousre by having the outer anonymous function on its scope chain,
hence there is a circular reference to p. Without the closure, there
can't be a circular reference. According to your theory, that
shouldn't happen - there is no "bound variable" and therefore no
closure, hence no circular reference.

I don't have IE around at the moment so I can't create a better test.
As far as I can discover, IE 7 still has the same problem so perhaps
you can test the code in either one?


> > If no variables are "bound", it becomes (probably) a useless closure, but
> > it's still there. Consider the classic IE leak:
>
> > function foo(id) {
> > var el = document.getElementById(id);
> > el.onclick = function(){};
> > }
>
> > The closure and circular reference occurs even though the function
> > assigned to the onclick property doesn't have any variables that
> > reference one of foo's variables.
>
> There may be a circular reference, but there certainly is no closure here.

How do you get a circular reference if there is no closure?


> >>> [snipped further irrelevance]
>
> > Lucky it was snipped then!
>
> Well, it would have been better had it not been in need of being snipped.

So I should know what you wish to respond to and only post that?

1. Javascript Closures, Scope chains and [[scope]]
<URL: http://www.jibbering.com/faq/faq_notes/closures.html#clScCh >

2. IE memory leak when removing elements from page? Inline
<URL: http://groups.google.com.au/group/comp.lang.javascript/msg/286fbae9eef6a2ef?hl=en
>


--
Rob

Lasse Reichstein Nielsen

unread,
Mar 21, 2009, 4:46:49 AM3/21/09
to
kangax <kan...@gmail.com> writes:

> So to make sure I understand this properly:
>
> // No closure is formed
> var foo;
> function bar(){};

Depending on your definition and the implementation.

The function declaration creates a function value. Whether it includes
the current scope in its scope chain is implementation dependent. The
specification specifies it as doing so, but the implementation will
work the same whether it does or not, since the function doesn't use
the scope, so it might be optimized away.

> // Closure is formed
> var foo;
> function bar(){
> return foo;
> }

Necessarily (at least if the current scope is not the global scope,
which might be available implicitly).

> What if Identifier is not present?
>
> var fn = (function(){
> var x = 5;
> return (function(){
> return eval(String.fromCharCode(120));
> })
> })();

When you use eval, the implementation has no way to know which
variables are used, so it must ensure that it can work the same way as
the specification no matter what string is evaluated. I.e., it needs
to retain the entire scope chain for all closures containing a potential
call to eval.

> I was under impression that returned function object (referred to by
> `fn` here) forms a closure during its evaluation as a function
> expression; that this closure includes calling context scope - context
> of an outer self-executing function - and that this scope has `x` as a
> property of its Activation/Variable object and so can be resolved from
> within returned `fn`:
>
> fn(); // 5
>
> What did I miss this time?

Nothing except a potential optimization when the implemetation can say
for sure that an outer scope isn't needed.

> I don't see any mention of explicit references in wikipedia article. I
> also can't remember ECMA-262 3rd Ed. specifying anything like that. It
> seems that ECMA scope forming mechanism speaks for itself - "scope
> objects" include *all* local variables (as properties of "captured"
> Activation/Variable object) and those scope objects are then chained
> together properly, as function objects are created and their
> [[Scope]]'s are being set. There's no discrimination against functions
> whose bodies do not contain explicit references, is there?

Not in the specification. But the specification does not require
implementations to implement itself, merely to have behavior that is
extensionally equivalent. Since a programmer can't see the [[Scope]]
chain of a function value, the implementation is free to implement
it however efficient it wants, as long as any variable that is actually
used will be resolved correctly.

/L
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'

Jorge

unread,
Mar 21, 2009, 7:50:47 AM3/21/09
to
On Mar 21, 12:15 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
>

> The object that is the caller of the function may have that property,
> however since that property is never referred within the function when it is
> defined, there is no closure:

^^^^^ that's false ^^^^^^ that's not the reason ^^^^

The proof:

var e;
e= (function a () {
var aContext= "_aData";
return (function b () {
var bContext= "_bData";
return (function c () {
var cContext= "_cData";
return (function d () {

return function e (p) {
return eval(p);
};

})();
})();
})();
})();

//At this point, no outer vars (unless you count eval) are referred to
within e, but there's a closure :

e('aContext+bContext+cContext'); // -> "_aData_bData_cData"

Instead : (*)

> Identifier resolution *along the scope chain* takes place when the function
> is executed, not when it is created. But the property of a closure is that
> it reproduces the execution context present when and in which it was defined

"A property" rather than "THE property" of a closure is that any
contexts in scope are, oh well, in scope (wait... don't need a closure
for that!).

Execution contexts are created when entering functions and destroyed
upon exit... *except when/if a closure is created*, and that's "THE
property" of a closure: that the contexts in scope are preserved (pre-
ser-ved, *not* reproduced) upon exiting the functions that created
them.

> when it is called (necessary), because there is some *explicit* reference in
> the subroutine to an identifier or name that is lexically defined outside of
> that subroutine (sufficient).

e() is called and there are no references in it to none of the
identifiers aContext, bContext or cContext. Game over. You lose.

(*)
"> when it is called (necessary)"
[x] e() is called.
"there is some *explicit* reference (to an outer var)"
[x] outer vars are explicitly referred to in e()...

...but still there ain't no closures (**) here PointedEars :

(function a () {
var aContext= "_aData";
return (function b () {
var bContext= "_bData";
return (function c () {
var cContext= "_cData";
return (function d () {
return (function e (p) {
return aContext+bContext+cContext;
})();
})();
})();
})();
})(); // -> "_aData_bData_cData"


(**) Why ? Because e() does not survive after execution the contexts
in its scope need *not* be preserved, which is "THE" property of a
closure. Nothing to do with bound variables, explicit or not.
--
Jorge.

John G Harris

unread,
Mar 21, 2009, 12:34:36 PM3/21/09
to

Shouldn't that be spelt kewl ?

John
--
John Harris

Jorge

unread,
Mar 21, 2009, 1:50:09 PM3/21/09
to

Do you know of a better way to isolate/lock an identifier ?
As for the spelling, spell it "kewl" if that's your liking.

--
Jorge.

kangax

unread,
Mar 22, 2009, 12:43:11 AM3/22/09
to
Lasse Reichstein Nielsen wrote:
> kangax <kan...@gmail.com> writes:
[...]

>> I don't see any mention of explicit references in wikipedia article. I
>> also can't remember ECMA-262 3rd Ed. specifying anything like that. It
>> seems that ECMA scope forming mechanism speaks for itself - "scope
>> objects" include *all* local variables (as properties of "captured"
>> Activation/Variable object) and those scope objects are then chained
>> together properly, as function objects are created and their
>> [[Scope]]'s are being set. There's no discrimination against functions
>> whose bodies do not contain explicit references, is there?
>
> Not in the specification. But the specification does not require
> implementations to implement itself, merely to have behavior that is
> extensionally equivalent. Since a programmer can't see the [[Scope]]
> chain of a function value, the implementation is free to implement
> it however efficient it wants, as long as any variable that is actually
> used will be resolved correctly.

I understand this. And I was actually basing my assumptions on
specification, rather than implementations. Saying that a closure is not
created because an implementation has all the reasons to do so (for
optimization purposes, or else) doesn't seem right. It seems backwards.

If anything, it makes more sense to say that a closure *might or might
not* be created (in some particular implementation) and the reason why
it might not be created is because it's clearly observable that it won't
be needed (runtime evaluation won't occur, identifiers are not present,
etc.)

So, getting back to the subject of `this` vs `calculator` in function
body, we can say that using former one has a chance of implementation
optimizations. Such potential optimizations can be useful.

I don't think it's right to say definitely that a former case *creates
no closure* and latter one does. Don't you think?

--
kangax

0 new messages