Are you a javascript expert? Test

O

optimistx

What does the alert statement in these 5 cases output, exactly?Of course,
the test should be done without debugger, without executing,without googling
, with honesty ...1)if (!("a" in window)) {
var a = 1;
}
alert(a);2)var a = 1,
b = function a(x) {
x && a(--x);
};
alert(a);3)
function a(x) {
return x * 2;
}
var a;
alert(a);4)
function b(x, y, a) {
arguments[2] = 10;
alert(a);
}
b(1, 2, 3);5)
function a() {
alert(this);
}
a.call(null);The code was copied (without doublechecking)
fromhttp://dmitry.baranovskiy.com/
 
R

Richard Cornford

What does the alert statement in these 5 cases output, exactly?
Of course, the test should be done without debugger, without
executing,without googling , with honesty ...

And presumably with the assumption that each single example is in
isolation. And preferably with some effort having been put in with
regard to providing a readable presentation.
1)if (!("a" in window)) {
var a = 1;}

alert(a);

The expected output is 'undefined', as the - a - variable is declared
but never assigned a value (because being declared the - "a" in window
- is true, at least it would have been guaranteed to be true of - "a"
2)var a = 1,
b = function a(x) {
x && a(--x);
};
alert(a);

The expected output is '1'. The JScript named function expression bug
came into play but the assignment of 1 to - a - happened after
variable instantiation so the reference to the extra function has been
replaced.
3)
function a(x) {
return x * 2;}

var a;
alert(a);

The expected output is 'function a(x)( return x * 2;}', but possibly
with formatting.
4)
function b(x, y, a) {
arguments[2] = 10;
alert(a);}

b(1, 2, 3);

The expected output is '10'.
5)
function a() {
alert(this);}

a.call(null);

The expected output is the string representation of the global object,
which is implementation dependent.
The code was copied (without doublechecking)

Or much thought going into presentation.
fromhttp://dmitry.baranovskiy.com/

Richard.
 
D

Dmitry A. Soshnikov

[...]
The JScript named function expression bug
came into play but the assignment of 1 to - a - happened after
variable instantiation so the reference to the extra function has been
replaced.

JScript NFE's bug doesn't matter in here, anyway result will be [1] -
with correct implementation of NFE or not.

[...]
The expected output is the string representation of the global object,
which is implementation dependent.

Yeah, but e.g. Google Chrome seems to distinguish real [undefined]
value and [not passed] parameter:

var getClass = Object.prototype.toString;

alert(getClass.call()); // [object Object]
alert(getClass.call(undefined)); // [object builtins]
alert(getClass.call(null)); // [object builtins]
alert(getClass.call(this)); // [object global]

First three calls should use the global object as [thisArg] (by
15.3.4.4, ES-3), and the fours one - is real global object passed (in
code of the global context), but as we can see Chrome treats this
cases differently.

/ds
 
J

Jorge

What does the alert statement in these 5 cases output, exactly ?
Of course,
the test should be done without debugger, without executing,
without googling, with honesty ...

function f () { return 1; }

if (true) {
function f () { return 2; }
} else {
function f () { return 3; }
}

alert(f()); // ?
 
D

Dmitry A. Soshnikov

function   f () { return 1; }

if (true) {
  function f () { return 2; }} else {

  function f () { return 3; }

}

alert(f()); // ?
[...]

By the spec, btw, this cases are *not correct* at all. In block can be
only *statments* (not expressions as we can thinks that it's function
expression). The only way that expression can appear in block is
Expression Statement which *cannot* starts from open bracket "{" and
"function" keyword. So theoretically, this code is incorrect.

But indeed, as specification allows *syntax extension* (16, ES-3) no
one implementation throws exception there but handles that code, but -
every by it's own. Spidermonkey's extension called *Function
Statement* - such a combination of (Function Declaration + Function
Expression) - this functions will be created in "runtime" (on parse
code level) but not on entering execution context like Function
Declarations are. Other implementations just create here simple FD
(and take the last one).

So,

FF - 2;
Other - 3
 
D

Dmitry A. Soshnikov

Back to IE (and it's implementation of NFE): what will alert show in
example above?

var referenceToNFE = function testNFE() {

alert([
arguments.callee === referenceToNFE,
arguments.callee === testNFE
]);

};

And in the next one?

referenceToNFE(); // [?, ?]
testNFE(); // [?, ?]

var referenceToNFE = function testNFE() {

alert([
arguments.callee === referenceToNFE,
arguments.callee === testNFE
]);

}(); // [?, ?]

;-)
 
D

Dmitry A. Soshnikov

And in the next one?
^^^^^^^^^^
referenceToNFE(); // [?, ?]
testNFE(); // [?, ?]

var referenceToNFE = function testNFE() { [next example]

Sorry, two calls are related to the first one example. So should be:

[...]
referenceToNFE(); // [?, ?]
testNFE(); // [?, ?]
 
D

Dmitry A. Soshnikov

Dmitry A. Soshnikov wrote:
[...]
Yeah, but e.g. Google Chrome seems to distinguish real [undefined]
value and [not passed] parameter:

You can always distinguish them by checking `arguments.length` value of
course.

Ah, that's just theoretical interest for me, no more; sure it's Chorme
implementations bug of call/apply methods.
var getClass = Object.prototype.toString;
alert(getClass.call()); // [object Object]

Strange. I actually get "[object builtins]" here as well (Chrome 4.x on
Mac). Which version are you on?

I have Chrome v.3.0.195.27 (WinXP). Yep, there were some changes in
4.x version, e.g. they removed JS-code implementation of native
methods from .toString:

In v.4.x you'll get standard:

alert([].push);

Result: function push() {[native code]}

And in 3.x sort of:

alert([].push);

function push() {
var n = ToUint32(this.length);
var m = _ArgumentsLength();
for (var i = 0; i < m; i++) {
this[i+n] = _Arguments(i);
}
this.length = n + m;
return this.length;
}
alert(getClass.call(undefined)); // [object builtins]
alert(getClass.call(null)); // [object builtins]

Well this just makes their implementation non-conformant.

Yes, it's.
It looks like "builtins" is the [[Class]] of
`undefined` and `null`, or more likely [[Class]] of their internal
wrappers or something (that somehow get past `call`/`apply`'s primitive
coercion).

Yeah, kind of, on implementation level they have special namespace for
that Builtins::(...) where that entities are described.
[...]
Yep. However, `toString` from <Global object>'s [[Prototype]] actually
returns "[object DOMWindow]". Apparently this next object in Global
Object's prototype chain is `DOMWindow.prototype` (where DOMWindow
doesn't seem to be exposed publicly).

(function(){ return this.__proto__.constructor; })();

/* function DOMWindow() { [native code] } */

So the proto chain there is apparently something like:

<Global Object> --> DOMWindow.prototype --> <...> --> Object.prototype

Yes, seems so, but e.g. FF also has "additional" objects in prototype
chain of the global object (not global -> Object.prototype directly):

alert(this.__proto__); // [xpconnect wrapped native prototype]
alert(this.__proto__.__proto__); // [object Global Scope Polluter]
alert(this.__proto__.__proto__.__proto__); // [object Object] -
Object.prototype appears only now
alert(this.__proto__.__proto__.__proto__.__proto__); // null, end of
the chain - Object.prototype.[[Prototype]]

/ds
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top