The quiz
Recently some JavaScript quizzes appear then and there with the competitive titles wondering whether “you know JavaScript”? The recent quizzes were by kangax, Dmitry Baranovskiy and by Nicholas C. Zakas. All that quizzes are interesting, many questions though are mostly theoretical rather than practical.
And again just for fun, I suggest another ECMAScript quiz. I won’t use some boring things such as “a+++b”; but I will more sophisticated
Some interesting questions are collected from newsgroups, mailing lists, forums and from my own.
Some features and difficulty level:
- almost all questions are theoretical; some of them are directly related to ECMA-262-3 specification;
- clear ECMAScript is used without non-standard features, augmentations of built-ins or any other extensions, though can be the case of user-defined global objects;
- objectively, the test is hard, but should not be so if you will be attentive;
- there are hard and easy questions;
- there are questions only on attention;
- if some questions seem to be hard, you can use console (that’s not a cheating, because some questions are hard).
- what’s the goal, when and where will I need to use this “useless” stuff on practice? – Usually, you won’t. This test is mostly theoretical, you may pass it or may not – that’s your choice.
Good luck.
typeof typeof(null)
2. Are the algorithms of the following checks completely equvalent?
typeof foo == 'undefined'
and
typeof foo === 'undefined'
100['toString']['length']
var a = (1,5 - 1) * 2
var x = 10;
var foo = {
x: 20,
bar: function () {
var x = 30;
return this.x;
}
};
console.log(
foo.bar(),
(foo.bar)(),
(foo.bar = foo.bar)(),
(foo.bar, foo.bar)()
);
function f(x, y) {
x = 10;
console.log(
arguments[0],
arguments[1]
);
}
f();
var
b = 10,
c = (
20,
function (x) { return x + 100},
function () { return arguments[0]}
);
a = b + c
({x: 10}).x
1..z
({
x: 10,
foo: function () {
function bar() {
console.log(x);
console.log(y);
console.log(this.x);
}
with (this) {
var x = 20;
var y = 30;
bar.call(this);
}
}
}).foo();
foreach (k in {a: 10, b: 20})
{
// ...
}

18. February 2010 at 20:12
Good stuff.
I messed up #9, thinking that `x` in `x, y, this.x` has value of `20`, not `undefined`. Then realized where the mistake was (`bar`’s VO is followed by `foo`’s VO, not the object that `with` injected into the scope; lexical scoping keeps biting me from time to time
).
Minor nitpicks: question #2 is debatable. I kind of understand what you mean by “[...] algorithms of the following checks completely equivalent”, but if we were to be precise, ‘undefined’ == ‘undefined’ and ‘undefined’ === ‘undefined’ go through different algorithms. Former one goes through “The Abstract Equality Comparison Algorithm” (11.9.3), whereas latter one — through “The Strict Equality Comparison Algorithm” (11.9.6). Both go through steps 1,2,3,4 and 11, but step 1 in 11.9.3 is technically not the same as step 1 in 11.9.6. Therefore, I can say that algorithms are different.
Finally, just as I mentioned on Zakas blog (http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/#comment-4568), it’s better to stay away from host objects (e.g. `alert`) as their unspecified nature makes questions ambiguous.
18. February 2010 at 21:31
Снова 50/50 =(
В последнем совсем ступил и посмотрел не туда.
18. February 2010 at 22:45
Объясните пожалуйста 5 вопрос, почему так, можно со ссылками на спецификацию
18. February 2010 at 22:58
Allright, I’ll bite… #2: two distinct algorithms are applied (but in effect they do the same thing, yes). #3: very nice, totally forgot about the radix parameter. #5: I do believe this should be 20,10,10,10, not 20,20,10,10 (the accepted solution). I had #6 wrong, but the result is just a comma, not “undefined”, when you alert it. #9 is a “with” scoping problem i never get right and #10 totally got me
(5/5)
18. February 2010 at 23:05
Good questions. All of these are related with specification, and there are no host objects. Would be great if, there site with quiz like yours and @kangax. People can improve their knowledge about ECMA-262 3 and perhaps 5 editions.
Regarding semicolon insertions:
a) SyntaxError
b) Transform to `;false;`
a) Syntax error
b) Transform to `;false;`
18. February 2010 at 23:32
A wonderful test. Congratulations.
18. February 2010 at 23:40
@qFox, #5, (foo.bar)() is exactly the same as foo.bar():
11.1.6 The Grouping Operator
The production PrimaryExpression : ( Expression ) is evaluated as follows:
1. Evaluate Expression. This may be of type Reference.
2. Return Result(1).
19. February 2010 at 01:00
Again regarding ASI. I see in ECMA-262 5, there still rules for automatic semicolon. And strict mode doesn’t make any sense about this. That is one of the “features”, which is total misconceptions in language. I can’t see any reasons to skip semicolon. I always put explicitly semicolon. Semicolon insertion is job for developer, not for Tokenizator of the language. Automatic insertion is bad design. That design is developed for people, which don’t give a damn about, where actually need semicolon. If developer doesn’t know where need be put semicolon, he should be read specification of the language, not rules for automatic semicolon insertion. Of course ES5 cannot remove automatic insertion because will break backward compatible. But i am wonder, why in strict mode, there still rules for ASI?
Regards for good question, and will be great if you post explanations about correct behavior.
Perhaps will be good if you create your own site in which you can post your articles, quiz’s and other things about ES. There you can build content on different languages, and for readers will be easy to understand your suggestions and articles. ;~)
19. February 2010 at 01:50
update:
Question #4 is changed from:
The correct answer was set to “global”. But this question is very ambiguous. By ES3 it should be “Catch-object with “e” property” although only some implementation conform to it (spec doesn’t say directly about this, though I myself was wondering once why this value in implementations is global but not catch-value) – you can see conforming implementations e.g. in Opera 10.10, or in current version of Rhino – they will return catch-object in this case.
But in ES5 this was recognized as a bug, and this value in this case should be set to global. So from the ES5 viewpoint the answer was correct. And if I directly mentioned in disclaimer that questions are for ES3, for do not make this question ambiguous, I decided to change this question on current (provided by @DmitryKorobkin):
Thanks to @ohunt
Dmitry.
19. February 2010 at 11:51
Thanks all who already passed the test. I necessarily will answer all questions but a bit latter (other may want to pass it too). You sure also can write your explanations to each other – it’s welcomed
19. February 2010 at 11:07
But they can use special object for augment Scope Chain during evaluation of `catch` statement. Object which in specification called activation in:
| 11.2.3 Function Calls
| 7. If Result(6) is an activation object, Result(7) is null.
| Otherwise, Result(7) is the same as Result(6)
Of course here that object isn’t “Activation Object” in context of “10 Execution Contexts”, but behavior is reasonable. You can use “NFE” for observing same behavior.
(function f() { window.alert(this); if ((f.recFlag = !f.recFlag)) { f(); } })();In second invokation of `f’, `this’ value should reffer object created on:
| 1. Create a new object as if by the expression newObject().
| 2. Add Result(1) to the front of the scope chain.
19. February 2010 at 13:42
Great and very sophisticated test, this one totally had me down
Thanks, I learned a lot.
19. February 2010 at 16:46
В мене питання щодо тесту #6.
ECMA-262, 3rd Edition, section 10.1.8:
For each non-negative integer, arg, less than the value of the length property, a property is created with name ToString(arg) and property attributes { DontEnum }. The initial value of this property is the value of the corresponding actual parameter supplied by the caller. The first actual parameter value corresponds to arg = 0, the second to arg = 1, and so on. In the case when arg is less than the number of formal parameters for the Function object, this property shares its value with the corresponding property of the activation object. This means that changing this property changes the corresponding property of the activation object and vice versa.
Тобто, на скільки я розумію, грубо кажучи, зміни x і arguments[0] мали б синхронізуватися. Власне, в хромі так і відбувається. В фаєрфоксі – ні. Хто правий і чи не мала б бути там відповідь “10, undefined”?
21. February 2010 at 13:24
@Alex Gromov
Моё недавнее объяснение в одном из топиков на Хабре: http://habrahabr.ru/blogs/javascript/84381/#comment_2519403
На форуме http://javascript.ru/forum/, вопрос изначально появился от Zeroglif (там же есть несколько объяснений): http://javascript.ru/forum/misc/5724-secrets-javascript-ninja.html#post34116
ECMA-262-3, 11.2.3 Вызовы функций – http://javascript.ru/ecma/part11#a-11.2.3 (важные пункты 6-8).
21. February 2010 at 14:12
@qFox
As already was mentioned bellow, the grouping operator doesn’t call GetValue, so after its work there’s still RefereceType value. Two last call GetValue, so there’re already functions but not value of ReferenceType, which means: this value = null => global.
Yes, there was alert([...]) used, I’ve changed it to console.log(…) which should show undefined.
Dmitry.
21. February 2010 at 15:03
@Asen Bozhilov
Yes, the behavior with second call of NFE in this case is also debatable. I guess implementations handle this case somehow specially, they know that if base object is determinate as that special object storing optional name of FE, then also null => global should be used for the this value. But that’s just the guess, I don’t see in spec explanation of it.
Also we know that some implementations create this identifier binding right in the activation object (e.g. Rhino, but the similar behavior we saw in newer versions of Firefox).
But regarding exactly catch clause, ECMA-262-5 really has clarification of this ambiguous “bug” (feature):
From “Annex D (informative). Corrections and Clarifications in the 5th Edition with Possible 3rd Edition Compatibility Impact” of ECMA-262-5:
Dmitry.
21. February 2010 at 15:43
@kunik
Seems, you can’t write in Russian, but understand English. So, sorry, I can’t write in your suggested language, and will answer in English.
From ECMA-262-3 10.1.8, bullet 2:
function foo(x) { x = 42; console.log(arguments.length); // 0 console.log(arguments[0]); // undefined return arguments[0]; } // number of actual // parameter values is 0 f(); // undefinedSo, in this case (no parameter passed) this property (arguments[0]) doesn’t share its value with the corresponding property of the activation object. And that’s why Chrome is wrong.
Dmitry.
21. February 2010 at 16:42
@Asen Bozhilov
Yeah, I’m thinking on it, maybe will be soon.
This questions are very interesting, thanks, Asen. For now I know at least two non-conformant implementations – IE (JScript) and Chrome (V8).
About the first case (ECMA-262-3, 7.4 Comments):
So the answer is (b) – Transform to `;false;`, as still there’s LineTerminator.
About the second case (ECMA-262-3, 7.4 Comments):
So the answer is also (b) – Transform to `;false;`, as again we have one LineTerminator. But IE and Chrome parse this case wrong and have SyntaxError.
Dmitry.
21. February 2010 at 17:37
update:
@joseanpg has provided a good explanation of the quiz (you can find it on his twitter page). Although, question #10 became debatable. In disclaimer there was said:
which if to be fair can make answer on question #10 wrong. So I’ve changed this point in disclaimer to:
although, simple global function – is an augmentation of the global object, and the global object – is a built-in object. And to keep this question more interesting (rather than just “Always ReferenceError”), I’ve clarified disclaimer point; but the answer of joseanpg fairly (if there’s no any user-defined functions) is correct too.
The main goal of this question is about automatic semicolon insertion (7.9, ECMA-262-3) and position of the open curly block’s bracket; “foreach” and “k” play minor role here. In contrast with:
// always SyntaxError foreach (k in {a: 10, b: 20}) { // ... }which always will provide SyntaxError and thus will help to avoid error in logic of the program if user-defined function “foreach” exists and open curly block’s bracket is set on the new line:
// ReferenceError or possibly no error // if "k" and "foreach" function exist foreach (k in {a: 10, b: 20}) { // ... }as it will be transformed to:
// function call foreach (k in {a: 10, b: 20}) // just a block ;{ // ... }Dmitry.
22. February 2010 at 00:53
@kangax
Yes, that’s it, [[Scope]] of `bar’ is already set; firstly this question appeared on es-discuss mailing list, there is also my explanation: https://mail.mozilla.org/pipermail/es-discuss/2010-February/010791.html
Well, yeah, the main goal of this question is in the same types of operands and which imperative actions are taken applying algorithms. As types are the same, step 1, can be omitted to make this question more interesting than just “No, different algorithms (names) are used”.
The goal is to show that there’s no need to write (how we can see in many frameworks) strict equality with typeof operator and string operand.
About debatable – I think it will be better to form (more) correctly question title. Any suggestions?
Yep, true, I changed it to console.log, which is also, btw, host
Dmitry.
22. February 2010 at 14:53
@Asen Bozhilov
Well, actually automatic semicolon insertion there’s in many languages (though, maybe it’s named differently), e.g. in Ruby, QML declarative, other. You can write (in Ruby):
or
the same result.
Yes, that’s true, that ECMAScript has some ambiguous (from the human logic viewpoint) features regarding to ASI (if not to know and not to understand how this mechanism works).
But in general, this idea can be not so bad. The question is in implementation and ES has some ambiguous cases in this place. That’s it.
What about me – I always put semicolon explicitly in ES. And about ES5 – yep, they could force put semicolon explicitly in “strict mode”, but as I already told in some forums – I believe “strict mode” feature itself as an error of language design. Be more exact – the error is not the “strict” technique as itself, but in distinguishing “strict” and “non-strict” modes, which will cause many useless holy wars and debates. Some will talk that’s professional code is only in strict – but that’s completely wrong.
By the truth, I think that ES has a bit overloaded syntax, I think it should omit some redundant C-style features, which is actually done in version 1.8 of SpiderMonkey – as you know there open curly brackets and return keyword in some cases are optional – the same can be with semicolon – maybe that’s why they do not force put it explicitly even in strict mode.
Dmitry.
22. February 2010 at 16:57
So, as it was mentioned above, a good explanation of this quiz was provided by @joseanpg and is available here: http://joseanpg.net/jslab/quiz/soshnikov/answers.html.
24. February 2010 at 00:20
Another very good explanation of the quiz, by @slicknet: http://www.nczonline.net/blog/2010/02/23/answering-soshnikovs-quiz/ (although, there’re two misconceptions for #3 and #6).
11. April 2010 at 14:40
Great test. Learned a lot from it!
14. April 2010 at 12:10
I enjoyed the test, and did find it difficult. It’s really interesting though to see how the correct answers differ from output in a Javascript console.
16. April 2010 at 06:59
A wonderful test.