Code One
if (!(“a” in window)) {
var a = 1;
}
alert(a);
Copy the code
This strange code looks something like this: “If window has no attribute A, define a variable a and assign 1”, you might think you should alert 1. Actually, alert is “undefined”. To understand what’s going on, there are four things you should know about JavaScript.
First, all global variables are properties of the window. Var a = 1 is exactly equivalent to window.a = 1. Second, all variable declarations are hositing to the top of their scope, a feature of JavaScript. Take a look at this example below
Alert (" a "in Windows). var a;Copy the code
The above example will alert “true” even if the variable is declared after alert(). This is because the JavaScript engine first scans all variable lives and hositing them to the top of the scope. The above code is equivalent to this:
var a; Alert (" a "in Windows).Copy the code
The third thing you should understand is that only variable declarations are hositing and variable initializations are not
var a = 1;
Copy the code
You can look at the above code in pieces
var a;
a = 1;
Copy the code
In fact, JavaScript engines do the same thing. When a variable is declared and initialized, JavaScript automatically splits the variable declaration and the variable initialization. So why is there no hositing variable initialization? This can affect variable values during code execution, leading to unexpected results.
The last point is JavaScript Scoping, which many newbies don’t understand and even experienced JavaScript programmers don’t fully understand. JavaScript scoping is so complicated because it looks like a member of the C language. Take a look at the following C program:
#include int main() { int x = 1; Printf (" % d ", x); // 1 if (1) { int x = 2; Printf (" % d ", x); // 2} printf(" %d ", x); / / 1}Copy the code
The output above is 121 because the C language has block-level scope, but JavaScript does not.
var x = 1; console.log(x); // 1 if (true) { var x = 2; console.log(x); // 2 } console.log(x); / / 2This is because JavaScript is a function-level scope. Statements like if do not create new scopes. Only functions create new scopes.
If you understand the above four points, you can certainly see why alert is "undefined" in the above example, and the above code actually executes this way.
var a;
if (!(“a” in window)) {
a = 1;
}
alert(a);
Copy the code
Alert = undefined; alert = undefined; alert = undefined; ("a" in window) returns false; The variable is declared but not initialized, so alert "undefined".
Code Two
Var a = 1, b = function a(x) {x &&a (-x); }; alert(a);Copy the code
This code looks a lot more complicated than it is. The result is Alert "1". Don't get too confused. Again, this code requires you to know three things about JavaScript.
First, variable declarations are promoted. We saw that in the last example. The second aspect is function declaration enhancement. All function declarations, like variable declarations, are promoted to the top of the current scope.
It is important to note that a function is declared as follows:
function functionName(arg1, arg2) {
// function body
}
Copy the code
This corresponds to a function expression, which is essentially a variable initialization assignment.
var functionName = function(arg1, arg2) {
//function body
};
Copy the code
Function expressions are not promoted. This is essentially variable initialization.
The third point is that you have to know and understand that function declarations override variable declarations but not variable initializations. To understand this, take a look at the following example
function value() { return 1; } var value; alert(typeof value); / / "function"Copy the code
The value above ends as function, even though the variable declaration appears after the function declaration. Function declarations take higher precedence in this case. But the following example has a different result.
function value() { return 1; } var value = 1; alert(typeof value); / / "number"Copy the code
Now value has a value of 1, and the variable initializes the overridden function declaration.
Let's look at another example:
var a = 1;
function foo() {
a = 10;
return;
function a() {}
}
foo();
alert(a);
Copy the code
The example above will alert 1, and the code above will actually execute like this,
var a;
function foo() {
function a() {}
a = 10;
return;
}
a = 1;
foo();
alert(a);
Copy the code
And that should make it easy for you to understand why it's one.
Going back to Code Two, that function is actually a function expression and even if it has a function name a, a function expression with a name is not considered a function declaration and therefore is not overridden by the variable declaration. However, you might find that the variable containing the function expression is B, and the function expression is named A. Function a() {} is a function declaration, so it will be overridden by variable initialization, meaning that calling a(--x) will throw an error. Other browsers allow calls to a(--x) in functions even if the number of type A is outside the function. Meanwhile, calling b(2) in IE raises an error but undefined in other browsers.
Code Two can be simplified to more correct and easy-to-understand Code as follows:
Var a = 1, b = function(x) {x &&b (-x); } alert(a);Copy the code
Code Three
function b(x, y, a) {
arguments[2] = 10;
alert(a);
}
b(1, 2, 3);
Copy the code
This code is relatively simple, you just have to answer 3, or 10. Ecma-262, 3rd Edition, 10. 1. Section 8 explains about arguments objects:
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. Buta collection of facts cannot be called at any time. The first actual parameter value buta pile 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.
In short, each argument is a copy of the same name in the Arguments object. I have arguments[0] about x, I have arguments[1] about Y, and I have arguments[2] about A. When b(1, 2, 3, 4) is passed in, arguments[3] does not refer to that variable, but it has a value of 4.
Obviously, alert is 10.
Code Four
var b = 5;
function a() {
var b = 10;
alert(this.b);
}
a.call(null);
Copy the code
You should understand two aspects of JavaScript.
First, you should understand what this object is. Consider the following example:
var object = {
method: function() {
alert(this === object);
}
}
object.method(); // true
Copy the code
In the above code, this refers to object, so the result is true. In the global scope, this refers to window, so the following this refers to window
function method() {
alert(this === window); //true
}
method();
Copy the code
If you understand the first point, you'll understand the second point, call(). Call () redefines the execution environment of the function, that is, the reference to this. The first argument will be a reference to this, and subsequent arguments will be passed to the function as arguments.
function method() {
alert(this === window);
}
method(); // true
method.call(document); // false
Copy the code
When method.call(document) is called, this will point to document.
What happens when the function passed in is null or undefined?
If thisArg is null or undefined, the called function is passed the global object as the this value. Otherwise, the called function is passed ToObject(thisArg) as the this value.
So the window is passed in
PS: There is also an apply() that is similar to call(), but has only two arguments. The second argument should be an array.
You can easily see that the answer is 5
Copy the code