On Nov 12, 2:30 am, ricardobeat <[EMAIL PROTECTED]> wrote:
> On Nov 11, 10:54 am, RobG <[EMAIL PROTECTED]> wrote:
>
> > No, it's not.  What object is the following functions called as
> > methods of:
>
> > (function(){})();
>
> window?

No, it isn’t called as a property of any object.  The function
expression inside the brackets is evaluated and a function object
returned.  It is then called.

> (function(){ alert(this) })();
>
> creating a block scope doesn't make the function float in limbo!

There is no such thing as block scope in javascript.  The function
exists only in the context of the expression: the expression is
evaluated to create an anonymous function object which is passed to
the call operator ()[1]  and executed.  Once execution ceases, it is
made available for garbage collection and can’t be called again.  So
in effect, it is “in limbo” for its entire existence.

In javascript, all objects essentially exist “in limbo”.  The only
thing that keeps them hanging around are references from object
properties or variables.  Once those references are removed, the
object becomes available for garbage collection (except for certain
cases where browsers erroneously keep the objects around, a phenomenon
perceived as a memory leak).

> > function foo() {};
> > foo.call({});
>
> In this case the function is being called as a method of a new empty
> object ({}) you just created, right?

Yes, that was my point.

The assertion was that a call using an unqualified identifier in the
global scope was the same calling the same identifier as a property of
the window object - it isn’t, although for all practical purposes the
result is about the same.   Given the function declaration:

function foo() {}

if the function is called as foo(), the identifier foo is resolved
along the scope chain and is found as a property of the activation
object.  It is then executed because of the call operator.  Since it’s
global code, the activation object is the global object.

If it is called as window.foo(), firstly the identifier window is
resolved along the scope chain.  When found, foo is resolved as a
property of the window object.  If not found on the object itself, the
prototype chain is searched (in browsers I’ve tested, window
[[prototype]] seems to be undefined so it’s a pretty short lookup).

In the first case, foo’s this keyword is set to the global object
because the spec says that if there is no object reference to assign
to it, use the global object.  In the second case, foo’s this keyword
is set to the window object because it has been called as a property
of window.  It just so happens that for most browsers, window ===
global.

In global code, the difference is very little in practical terms.  But
in other contexts (say within a function) the difference is
substantial.

The larger issue is that it may appear that code called in the global
scope behaves differently to code called elsewhere, but it doesn’t.
Functions called from global code aren’t called as properties of the
window object.

1.  My terminology - there is no call operator in the ECMA-262 spec
but I need to give it a name for convenience rather than “empty formal
parameter list” or such.


--
Rob

Reply via email to