List of questions

  • Why does this code obj.someprop.x raise an error?
  • What is Event.target?
  • What is event.currenttarget?
  • What’s the difference between == and ===?
  • Why does JS return false when comparing two similar objects?
  • !!!!! What can an operator do?
  • How do I evaluate multiple expressions in a single line?
  • What is ascension?
  • What is scope?
  • What is a closure?

11. Why does obj.someprop.x cause an error?

const obj = {};
console.log(obj.someprop.x);
Copy the code

Obviously, since we are trying to access the X property in the someprop property and someprop is not in the object, the value is undefined. Remember that the object itself does not have an attribute, and its stereotype defaults to undefined. Because undefined does not have an attribute x, attempts to access it will result in an error.

12. What is Event.target?

Simply put, event.target is the element that produces the event or that triggers the event. Suppose you have the following HTML structure:

<div onclick="clickFunc(event)" style="text-align: center; margin:15px; border:1px solid red; border-radius:3px;" > <div style="margin: 25px; border:1px solid royalblue; border-radius:3px;" > <div style="margin:25px; border:1px solid skyblue; border-radius:3px;" > <button style="margin:10px"> </div> </div> </div>  function clickFunc(event) { console.log(event.target); }Copy the code

If we click button, even if we append the event to the outermost div, it will print the Button label, so we can conclude that event.target is the element that triggers the event.

13. What is event.currenttarget??

Event.currenttarget is the element on which we explicitly attach an event handler. Suppose you have the following HTML structure:

<div onclick="clickFunc(event)" style="text-align: center; margin:15px; border:1px solid red; border-radius:3px;" > <div style="margin: 25px; border:1px solid royalblue; border-radius:3px;" > <div style="margin:25px; border:1px solid skyblue; border-radius:3px;" > <button style="margin:10px"> </div> </div> </div>  function clickFunc(event) { console.log(event.currentTarget); }Copy the code

If we click button, even if we click the button, it will print the outermost DIV tag. In this example, we can conclude that event.currenttarget is the element to attach the event handler.

14. What’s the difference between == and ==?

== is used for general comparison, === is used for strict comparison, == can convert data types when comparing, === strict comparison, if the type does not match flase is returned.

  • Let’s take a look at this brother:

Coercion is the process of converting a value to another type. In this case, == performs implicit coercion. Before comparing two values, == needs to perform some rules.

  1. Suppose we want to compare x equals y.
  2. If x and y are of the same type, JS will replace them with the === operator for comparison.
  3. If x is null and y is undefined, true is returned.
  4. Return true if x is undefined and y is null.
  5. If x is of type number and y is of type string, return x == toNumber(y).
  6. If x is of type string and y is of type number, return toNumber(x) == y.
  7. If x is of type Boolean, return toNumber(x)== y.
  8. If y is type Boolean, return x == toNumber(y).
  9. If x is string, symbol, or number, and y is of type Object, return x == toPrimitive(y).
  10. If x is object and y is string, symbol returns toPrimitive(x) == y.
  11. Return false for the rest

Note: toPrimitive first uses the valueOf method in the object, and then the toString method to get the original valueOf the object. Let me give you an example.

X y x == y 5 5 true 1' 1' true null undefined true 0 false true '1,2' [1,2] true '[object object]' {} trueCopy the code

These examples all return true. The first example satisfies condition 1 because x and y have the same type and value. The second example meets condition 4 and converts y to a number before comparing. The third example satisfies condition 2. The fourth example satisfies condition 7 because y is Boolean. The fifth example meets condition 8. The array is converted to a string using the toString() method, which returns 1,2. The last example satisfies condition 8. An object is converted to a string using the toString() method, which returns [Object object].

X y x === y 5 5 true 1' 1' false NULL undefined false 0 false false '1,2' [1,2] false '[object object]' {} falseCopy the code

If the === operator is used, all comparisons except the first example will return false because they are of different types, and the first example will return true because both have the same type and value.

15. Why return false when comparing two similar objects in JS?

Take a look at the following example:

let a = { a: 1 }; let b = { a: 1 }; let c = a; console.log(a === b); // Print false, even though they have the same property console.log(a === c); // trueCopy the code

JS compares objects and primitive types in different ways. In primitive types, JS compares them by value, while in objects, JS compares variables by reference or by an address in memory where they are stored. This is why the first console.log statement returns false and the second console.log statement returns true. A and C have the same reference address, while A and B do not.

16.!!!!! What can an operator do?

!!!!! The operator can cast the value on the right to a Boolean, which is an easy way to convert a value to a Boolean.

console.log(!! null); // false console.log(!! undefined); // false console.log(!! "); // false console.log(!! 0); // false console.log(!! NaN); // false console.log(!! "); // true console.log(!! {}); // true console.log(!! []); // true console.log(!! 1); // true console.log(!! [].length); // falseCopy the code

17. How do I evaluate multiple expressions in a single line?

Multiple expressions can be evaluated on a single line using the comma operator. It evaluates from left to right and returns the value of the last item or operand on the right.

let x = 5; 
x = (x++ , x = addFive(x), x *= 2, x -= 5, x += 10);    
function addFive(num) {
  return num + 5;
}
Copy the code

The result above ends up with an x value of 27. First, we increase the value of x to 6, then call the function addFive(6) and pass 6 as an argument and reassign the result to X, where x has a value of 11. After multiplying the current value of x by 2 and assigning it to X, the updated value of x is 22. Then, subtract 5 from the current value of x and assign the result to x, where the updated value is 17. Finally, we increase the value of x by 10, and then assign the updated value to x, which ends up being 27.

18. What is promotion?

Promotion is the term used to describe moving variables and functions to the top of their (global or function) scope. To understand promotion, you need to understand the execution context. The execution context is the ** “code environment” ** that is currently executing. The execution context has two phases: compile and execute compile – at this stage, JS referrals take all function declarations and promote them to the top of their scope so that we can reference them later and get all variable declarations (declared using the var keyword), and provide them with a default value: undefined. Execute – In this phase, it assigns values to previously promoted variables and executes or calls functions (methods in objects). ** Note :** Only variables declared using var, or function declarations, are promoted. In contrast, function expressions or arrow functions, let and const variables are not promoted. Assume that in the global use domain, there is code like this:

console.log(y); y = 1; console.log(y); console.log(greet("Mark")); function greet(name){ return 'Hello ' + name + '! '; } var y;Copy the code

Undefined,1, Hello Mark! . The above code actually looks like this at compile time:

function greet(name) { return 'Hello ' + name + '! '; } var y; /* console.log(y); /* console.log(y); y = 1; console.log(y); console.log(greet("Mark")); * /Copy the code

Once the compile phase is complete, it starts the execution phase calling the method and assigning values to variables.

function greet(name) { return 'Hello ' + name + '! '; } var y; //start "execution" phase console.log(y); y = 1; console.log(y); console.log(greet("Mark"));Copy the code

19. What is scope?

A scope in JavaScript is an area where we can effectively access a variable or function. JS has three types of scope: global scope, function scope and block scope (ES6). Global scope – Variables or functions declared in the global namespace are in the global scope, so they can be accessed anywhere in the code.

//global namespace
var g = "global";

function globalFunc(){
  function innerFunc(){
    console.log(g); // can access "g" because "g" is a global variable
  }
 innerFunc();
}  
Copy the code

Function scope — Variables, functions, and parameters declared in a function can be accessed inside the function, but not outside the function.

function myFavoriteFunc(a) {
  if (true) {
    var b = "Hello " + a;
  }
  return b;
}

myFavoriteFunc("World");

console.log(a); // Throws a ReferenceError "a" is not defined
console.log(b); // does not continue here 
Copy the code

Block scope – Variables declared in block {} (let, const) can only be accessed in it.

 function testBlock(){
   if(true){
     let z = 5;
   }
   return z; 
 }

 testBlock(); // Throws a ReferenceError "z" is not defined
Copy the code

A scope is also a set of rules for finding variables. If the variable does not exist in the current scope, it looks up and searches the outer scope. If the variable does not exist, it looks again until it reaches the global scope. If it finds it, it can use it, otherwise it raises an error.

Var variable1 = "Comrades"; var variable2 = "Sayonara"; Function outer(){var variable1 = "World"; Function inner(){var variable2 = "Hello"; console.log(variable2 + " " + variable1); } inner(); } outer(); // Hello WorldCopy the code

What is a closure?

This is probably the most difficult question of all, because closures are a controversial topic, so here’s a personal one. A closure is a function that, when declared, remembers the current scope, the parent function scope, and references to variables and parameters in the parent function scope, up to the global scope on the scope chain. Basically, a closure is a scope created when the function is declared. Take a look at a small example:

Var globalVar = "ABC "; function a(){ console.log(globalVar); } a(); // "abc"Copy the code

In this example, when we declare a function, the global scope is part of the A closure.

The reason the globalVar variable has no value in the diagram is that its value can change depending on where and when function A is called. But in the example above, the globalVar variable has the value ABC. Let’s look at a more complicated example:

var globalVar = "global";
var outerVar = "outer"

function outerFunc(outerParam) {
  function innerFunc(innerParam) {
    console.log(globalVar, outerParam, innerParam);
  }
  return innerFunc;
}

const x = outerFunc(outerVar);
outerVar = "outer-2";
globalVar = "guess"
x("inner");
Copy the code

It printed guess Outer inner. When we call outerFunc and assign the innerFunc function with the return value to variable X, outerParam keeps the outer value even if we assign the outerVar variable outer-2 because the reallocation happens after outerFunc is called, And when we call the outerFunc function, it looks for the value of outerVar in the scope chain, which will be “outer”. Now, when we call the X variable that references innerFunc, innerParam will have an inner value, because that’s the value we passed in the call, and the globalVar variable will have a guess value, because we assigned a new value to globalVar before calling the X variable. The following example demonstrates the error of not understanding closures well:

const arrFuncs = []; for(var i = 0; i < 5; i++){ arrFuncs.push(function (){ return i; }); } console.log(i); // i is 5 for (let i = 0; i < arrFuncs.length; i++) { console.log(arrFuncs[i]()); // All prints 5}Copy the code

This code does not work due to closures. The var keyword creates a global variable, the global variable I that is returned when we push a function. So when we call one of these functions in that array after the loop, it prints 5, because we get the current value of I is 5, and we can access it because it’s a global variable because the closure keeps a reference to that variable instead of its value when it creates the variable. We can use IIFES or let instead of var declarations.