Disclaimer: Of course there are always many ways to solve a problem, so the answers listed make no
claim of authority, or even of "best approach." You are welcome to email sstchur(at)yahoo(dot)com if you'd like to see an
alternate answer listed.
What is the result of the following?
function foo()
{
alert(x);
var x = 10;
}
foo();
Runtime error
Will alert undefined
WIll alert 10
B. Why? It is perfectly valid to refer to the variable x before you assign it a value
provided that you have declared it somewhere in the function. The Javascript interpreter
actually rewrites the above as:
function foo()
{
var x;
alert(x);
x = 10;
}
foo();
What is the result of the following?
function foo()
{
x = 10;
alert(x);
}
foo();
alert(x);
Runtime error
Will alert 10 once
Will alert 10, followed by a runtime error
Will alert 10 twice
D. Why? x was created as an implicit global, meaning that it springs into existence
when first encountered and continues to exist in the global space, even outside of the foo function.
What is the result of the following?
function foo()
{
alert(y);
y = 10;
}
foo();
Runtime error
Will alert undefined
Will alert 10
A. Without the var keyword, what you are attempting to define is an "implicit global"
(yes, a real thing in Javascript). But the implicit global only springs into existence when that line is
encountered. Since you attempted to reference the variable, y, before it was declared, it will result in
a runtime error.
(Hint: use Firebug to see the error)
What is the result of the following?
function bar()
{
foo();
var foo = function()
{
alert(99);
};
}
bar();
Runtime error
Will alert 99
Neither of the above
A. Javascript rewrites the above as:
function bar()
{
var foo;
foo();
foo = function()
{
alert(99);
}
}
bar();
Javascript recognizes the varible foo as having been declared staright away, but it doesn't
get assigned a value until that line of code is encountered. Thus, foo is undefined when the
call, foo() attempts to execute.
(Hint: use Firebug to see the error)
What is the result of the following?
function bar()
{
foo()
function foo()
{
alert(99);
}
}
bar();
Runtime error
Will alert 99
None of the above
B. This time, foo was declared using a subtly different syntax. The Javascript
interpreter sees it as:
function bar()
{
function foo()
{
alert(99);
}
foo();
}
What is the result of the following?
function foo()
{
for (var i = 0; i < 5; i++)
{
alert(i);
}
alert(i);
}
foo();
Runtime error
Will alert: 0, 1, 2, 3, 4, undefined
Will alert: 0, 1, 2, 3, 4, {runtime error}
Will alert: 0, 1, 2, 3, 4, 5
D. Loops and if-statements do not have scope in Javascript. The variable, i, is
scoped to the function foo, but not to the for loop. It continues to exist even after the for loop
is finished. Therefore, the recommended syntax is:
var i;
for (i = 0; i < 5; i++) { ... }
This makes more explicit, what the Javascript interpreter is already doing for you anyway.
True or False?
function Foo()
{
var bestBand = 'Jimmy Eat World';
this.tellMe = function()
{
alert(bestBand);
};
}
var f1 = new Foo();
var f2 = new Foo();
alert(f1.tellMe === f2.tellMe); // true or false?
True
False
B. False Each instance of a Foo has its own .tellMe function.
True or False?
function Foo()
{
this.bestBand = 'Jimmy Eat World';
}
Foo.prototype.tellMe = function()
{
alert(this.bestBand);
};
var f1 = new Foo();
var f2 = new Foo();
alert(f1.tellMe === f2.tellMe); // true or false?
True
False
A. True Using prototype means that the every instance of a Foo shares the same .tellMe function
What is the result of the following?
var X =
{
x: 10,
y: 20,
foo: X.x * 9
};
Runtime error
Creates an object like, { x: 10, y: 20, foo: 90 }
None of the above
A. X is not fully initialized until the final curly brace, } is reached.
But the proeprty foo attempts to access a property of X, before X is fully initialized.
(Hint: Use Firebug to see the error)
What is the result of the following?
var X =
{
x: 10,
y: 20,
foo: this.x * 9
};
alert(X.foo); // just for demonstration purposes, not part of the question
Creates an object like, { x: 10, y: 20, foo: NaN }
None of the above
D. "this" does not refer to X, and this.x is therefore undefined. The undefined type
multiplied by 9 returns in NaN (which is toxic by the way). In this case, "this" would refer to the
Window, so something like this would be acceptable:
var X =
{
x: 10,
y: 20,
foo: this.location.href
};
What is the result of the following?
var i = 5;
while (i--)
{
setTimeout(function()
{
alert(i);
}, 100);
}
Will alert: 5, 4, 3, 2, 1
Will alert: 4, 3, 2, 1, 0
Will alert: 5, 4, 3, 2, 1, 0
Will alert: -1, -1, -1, -1, -1
D. The while loop will executes 5 times (until i is 0). The variable, i, will then be
decremented one additional time. Each iteration in the loop queues up a setTimeout call,
but those calls are non-blocking, so the while loop essentially finishes "immediately" and
when it does, the value of i is -1.
Rewrite the code in Question 11 to so that it work as "expected" (that is, it alerts 5, 4, 3, 2, 1)
var i = 5;
while (i--)
{
setTimeout(function(x)
{
return function()
{
alert(x);
}
}(i+1), 100);
}
Why it works: The while loop will execute 5 times. Each iteration makes a call
to setTimeout, passing in a function that is executed immediately and which returns a new function
reference. The outer function takes an argument, x, which is given the value of i+1 as the loop
iterates. The inner function now has access to x, even after it has seemingly gone out of scope.
It's like creating a "snapshot" of i as we loop and storing it away for later use.
Using the code in Question 12 as a starting point, modify the code to alert: 5, 4, 3, 2 and then 1,
where each alert happens roughly 2 seconds apart.
var i = 5;
while (i--)
{
setTimeout(function(x)
{
return function()
{
alert(x);
}
}(5-i), i*2000);
}
Why it works: Because it is essentially the equivalent of:
What is the value of y in the following code snippet?
var x = 10;
var y = 'steve_' + (x == 10) ? 'C' : 'D';
alert(y); // For demonstrations purposes, not part of the question
'steve_C'
'steve_D'
'C'
'D'
None of the above
C. Parenthesis are evaluated first and the result of (10 == 10) is true.
Next, 'steve_' will be concatenated with the bool, true, which will be coerced into a string
'true', yielding 'steve_true' Finally, 'steve_true' will be evaluated for "truthfulness"
(that is, is it considered truth-like, or false-like?) and the result is truth-like (as it is
not: null, undefined, "", 0, NaN, or false). Since the left side of the ? evaluates to true,
the 'C' will be used as the return value.
Rewrite the code in Question 14 to produce the "expected" result (that is, 'Steve_C')
var x = 10;
var y = 'steve_' + (x == 10 ? 'C' : 'D');
alert(y); // For demonstration purposes, not part of the question
Why it works: Proper use of parenthesis ensures that the ternary operator is evaluated
first and the result is then concatenated with 'steve_'
Write a function, setTimeoutX, which takes 3 arguments (fnRef, ms, a). fnRef is a reference to a function
that should be executed after ms milliseconds have elapsed, and the variable, a, should be passed into
fnRef, when that function executes.
function setTimeoutX(fnRef, ms, a)
{
setTimeout(function()
{
fnRef(a);
}, ms);
}
// test it out
function foo(x)
{
alert(x);
}
setTimeoutX(foo, 1500, 'steve');
Why it works: setTimeoutX creates a closure around the variable, a, which
can then be referenced passed into the fnRef function when it is called.
BONUS! Write a function, setTimeoutX, which takes N arguments, the first two of which are
fnRef and ms, followed by any number of additional arguments which should be passed into the fnRef function when
it executes after a delay of ms milliseconds.
function setTimeoutX(fnRef, ms)
{
var args = arguments;
setTimeout(function()
{
fnRef.apply(window, Array.prototype.slice.call(args, 2));
}, ms);
}
// test it out
function add(a, b, c, d)
{
alert(a + b + c + d);
}
setTimeoutX(add, 1500, 5, 10, 15, 20);
Why it works: A closure is created in the same manner as the answers to Question 16, but
this time, we capture the arguments variable (a "special" variable available in every javascript function
which is an array-like object containing all passed in arguments).
We then leverage the .apply method (all javascript functions can be invoked with .apply) which allows
you to specify the "this" object (1st arg) and the arguments to pass into said function, given as an
array.
The args variable however, contains ALL arguments (even fnRef and ms, which we don't want to pass to fnRef).
So we use the native Array's slice method to pull out all but the first two arguments.