List of questions
- What are imaginary values in JavaScript?
- How do I check if a value is virtual?
- What is ‘use strict’ for?
- What is the value of this in JavaScript?
- What is the prototype of the object?
- What is IIFE and what is it used for?
- Function.prototype. what is the use of the apply method?
- What is the Function. Prototype. call method used for?
- What’s the difference between function.prototype. apply and function.prototype. call?
- What is function.prototype. bind used for?
21. What are imaginary values in JavaScript?
const falsyValues = [”, 0, null, undefined, NaN, false];
Simply put, an imaginary value is a value that becomes false when converted to a Boolean value.
22. How do I check whether a value is virtual?
Use Boolean functions or!! Operator.
23. What is ‘use strict’ for?
“Use strict” is an ES5 feature that puts our code in strict mode within a function or entire script. Strict mode helps us avoid bugs early in the code and adds restrictions to it.
Some limitations of strict mode:
- Variables must be declared before being used
- Function arguments cannot have attributes of the same name; otherwise, an error is reported
- The with statement cannot be used
- Cannot assign a value to a read-only attribute, otherwise an error is reported
- Octal numbers cannot be represented with the prefix 0, otherwise an error is reported
- You cannot delete attributes that cannot be deleted; otherwise, an error is reported
- Cannot delete variable delete prop, error will be reported, only delete property delete global[prop]
- Eval cannot introduce variables in its outer scope
- Eval and arguments cannot be reassigned
- Arguments do not automatically reflect changes to function arguments
- Arguments.callee cannot be used
- Can’t use arguments.caller
- Disallow this from pointing to a global object
- You cannot use fn.caller and fn.arguments to get the stack of function calls
- Added reserved words (such as protected, static, and interface)
The main objectives of the Strict Mode are as follows:
- Eliminate some unreasonable and inaccurate Javascript syntax, reduce some weird behavior;
- Eliminate some unsafe code operation, to ensure the safety of code operation;
- Improve the efficiency of the compiler, increase the running speed;
- Set the stage for future versions of Javascript.
24. What is this value in JavaScript?
Basically, this refers to the value of the object on which the function is currently being executed or called. The value of this varies depending on the context in which we use it and where we use it.
const carDetails = {
name: "Ford Mustang",
yearBought: 2005,
getName(){
return this.name;
},
isRegistered: true
};
console.log(carDetails.getName()); // Ford Mustang
Copy the code
This is usually what we expect, because in the getName method we return this.name, and in this context this points to the carDetails object, which is currently the “owner” object of the executing function. Now let’s do something weird:
var name = "Ford Ranger";
var getCarName = carDetails.getName;
console.log(getCarName()); // Ford Ranger
Copy the code
It prints Ford Ranger, which is strange because Ford Mustang is printed in the first console.log statement. The reason for this is that the getCarName method has a different “owner” object, the Window object. Declaring a variable using the var keyword in the global scope appends the same properties to the window object as the variable name. Remember, when “use strict” is not used, this refers to the window object in the global scope.
console.log(getCarName === window.getCarName); // true
console.log(getCarName === this.getCarName); // true
Copy the code
In this case, this and Window refer to the same object. One way to solve this problem is to use the Apply and call methods in functions
console.log(getCarName.apply(carDetails)); // Ford Mustang
console.log(getCarName.call(carDetails)); // Ford Mustang
Copy the code
The Apply and Call methods expect the first argument to be an object that is the value of this inside the function. IIFE or immediately-executed function expressions, functions declared in global scope, anonymous functions in methods inside the object, and this of the internal function have default values that point to the window object.
(function (){ console.log(this); }) (); Function iHateThis(){console.log(this); } iHateThis(); // Print "window" object const myFavoriteObj = {guessThis(){function getName(){console.log(this.name); } getName(); }, name: 'Marko Polo', thisIsAnnoying(callback){ callback(); }}; myFavoriteObj.guessThis(); / / print "window" object myFavoriteObj. ThisIsAnnoying (function () {the console. The log (this); // Print the "window" object});Copy the code
If we want to get the value of the Name attribute (Marko Polo) in the myFavoriteObj object, there are two ways to solve this problem. One is to store the this value in a variable.
const myFavoriteObj = { guessThis(){ const self = this; Function getName(){console.log(self.name); } getName(); }, name: 'Marko Polo', thisIsAnnoying(callback){ callback(); }};Copy the code
The second way is to use the arrow function
const myFavoriteObj = { guessThis(){ const getName = () => { console.log(this.name); } getName(); }, name: 'Marko Polo', thisIsAnnoying(callback){ callback(); }};Copy the code
Arrow functions do not have their own this. It copies the closed lexical scope this value, which in this case is outside the getName inner function, the myFavoriteObj object.
25. What is the prototype of the object?
Simply put, a prototype is a blueprint for an object. If it exists in the current object, it is used as a fallback for properties and methods. It’s a way of sharing properties and functionality between objects, which is at the heart of JavaScript implementation inheritance.
const o = {};
console.log(o.toString()); // logs [object Object]
Copy the code
Even if the O.tostring method does not exist in the O object, it does not raise an error, but returns the string [Object object]. When an object does not have an attribute, it looks at its prototype, and if it still does not, it looks to the prototype’s prototype, and so on, until it finds an attribute with the same attribute in the prototype chain. At the end of the prototype chain is Object.Prototype.
console.log(o.toString === Object.prototype.toString); // logs true
Copy the code
26. What is IIFE and what is it used for?
An IIFE or immediately invoked function expression is a function that will be called or executed after it has been created or declared. The syntax for creating IIFE is to wrap function (){} in parentheses () and then call it with another parentheses (),
(function(){})() (function(){... } ()); (function () { ... }) (); (function named(params) { ... }) (); (() = > {}); (function (global) { ... })(window); const utility = (function () { return { ... }})Copy the code
These examples are valid IIFE. The penultimate save indicates that we can pass arguments to the IIFE function. The last example shows that we can save IIFE results to variables for later use. One of the main functions of IIFE is to avoid naming conflicts with other variables in the global scope or contaminating the global namespace, for example.
<script src="https://cdnurl.com/somelibrary.js"></script>
Copy the code
Suppose we introduce a link to omelibr.js that provides some global functions that we use in our code, but the library has two methods that we don’t use: createGraph and drawGraph, because those methods are buggy. We want to implement our own createGraph and drawGraph methods. One way to solve this problem is to override it directly:
<script src="https://cdnurl.com/somelibrary.js"></script>
<script>
function createGraph() {
// createGraph logic here
}
function drawGraph() {
// drawGraph logic here
}
</script>
Copy the code
When we use this solution, we override the two methods that the library provides us. Another way is to change the name ourselves:
<script src="https://cdnurl.com/somelibrary.js"></script>
<script>
function myCreateGraph() {
// createGraph logic here
}
function myDrawGraph() {
// drawGraph logic here
}
</script>
Copy the code
When we use this solution, we change those function calls to the new function names. Another way is to use IIFE:
<script src="https://cdnurl.com/somelibrary.js"></script>
<script>
const graphUtility = (function () {
function createGraph() {
// createGraph logic here
}
function drawGraph() {
// drawGraph logic here
}
return {
createGraph,
drawGraph
}
})
</script>
Copy the code
In this solution, we declare the graphUtility variable to store the results of IIFE execution, and this function returns an object containing the two methods createGraph and drawGraph.
IIFE can also be used to solve a common interview question:
var li = document.querySelectorAll('.list-group > li');
for (var i = 0, len = li.length; i < len; i++) {
li[i].addEventListener('click', function (e) {
console.log(i);
})
Copy the code
Suppose we have a UL element with a list-group class that has five li child elements. When we click on a single LI element, we print the corresponding subscript value. But in addition to that the above code doesn’t work, here each click on Li prints the value of I is 5 because of the closure. Closures are simply the function’s ability to remember variable references to its current scope, parent function scope, and global scope. Global variable I is created when we declare variables in the global scope using the var keyword. Therefore, when we click on the Li element, it will print 5 because that is the value of I when it is referenced later in the callback function. Using IIFE you can solve this problem:
var li = document.querySelectorAll('.list-group > li');
for (var i = 0, len = li.length; i < len; i++) {
(function (currentIndex) {
li[currentIndex].addEventListener('click', function (e) {
console.log(currentIndex);
})
})(i);
}
Copy the code
This solution works because IIFE creates a new scope for each iteration, and we capture the value of I and pass it to the currentIndex parameter, so IIFE is called with a different currentIndex value for each iteration.
Prototype. What is the use of the apply method?
The apply() method calls a function with a given this value and the arguments supplied as an array (or array-like object).
const details = { message: 'Hello World! '}; function getMessage(){ return this.message; } getMessage.apply(details); // 'Hello World! 'Copy the code
The call() method is similar to apply() except that call() takes a list of parameters, while apply() takes an array of parameters.
const person = {
name: "Marko Polo"
};
function greeting(greetingMessage) {
return `${greetingMessage} ${this.name}`;
}
greeting.apply(person, ['Hello']); // "Hello Marko Polo!"
Copy the code
28. What is the Function. Prototype. call method used for?
The call() method calls a function with a specified this value and one or more arguments given separately.
const details = { message: 'Hello World! '}; function getMessage(){ return this.message; } getMessage.call(details); // 'Hello World! 'Copy the code
Note: The syntax and actions of this method are similar to those of apply(), except that call() accepts a list of arguments, while apply() accepts an array of arguments.
const person = {
name: "Marko Polo"
};
function greeting(greetingMessage) {
return `${greetingMessage} ${this.name}`;
}
greeting.call(person, 'Hello'); // "Hello Marko Polo!"
Copy the code
29. What’s the difference between function.prototype. apply and function.prototype. call?
The apply() method can invoke a function or method that uses a specified this value and an array of arguments (or array-like objects). The call() method is similar to apply(), except that call() takes a list of arguments.
const obj1 = { result:0 }; const obj2 = { result:0 }; function reduceAdd(){ let result = 0; for(let i = 0, len = arguments.length; i < len; i++){ result += arguments[i]; } this.result = result; } reduceAdd.apply(obj1, [1, 2, 3, 4, 5]); // 15 reduceAdd.call(obj2, 1, 2, 3, 4, 5); / / 15Copy the code
30. Function.prototype.bind is used for what?
The bind() method creates a new function, and when bind() is called, this of the new function is specified as the first argument to bind(), and the remaining arguments will be used as arguments to the new function.
import React from 'react'; class MyComponent extends React.Component { constructor(props){ super(props); this.state = { value : "" } this.handleChange = this.handleChange.bind(this); HandleChange (e){//do something amazing here} render(){return (<> <input) type={this.props.type} value={this.state.value} onChange={this.handleChange} /> </> ) } }Copy the code