[Front-end interview questions] 2023 National Day front-end interview real questions - JS chapter

There are always ups and downs in a person's life. It will not always rise like the rising sun, nor will it always be miserable. Repeated ups and downs are training for a person. Therefore, those who are floating above do not need to be proud; those who are sinking below do not need to be pessimistic. We must be frank and humble, optimistic and enterprising, and move forward. ——Konosuke Matsushita

Hello everyone, my name is Jiang Chen. In today's Internet environment, everyone must have felt it to some extent. In this impetuous society, only by constantly maintaining one's character can one perceive different gains and encourage each other.

A collection of the latest interview questions in 2023, so be prepared at all times.

Front-end interview question bank ( essential for interviews) Recommended: ★★★★★            

Address: Front-end interview question bank

 My cousin made her own five-star red flag National Day avatar with just one click. It’s super nice.

Please briefly describe this in JavaScript

JS  this is a relatively complex concept that cannot be explained clearly in a few sentences. Roughly speaking, the way the function is called determines  this the value of . I read a lot of  this articles about it on the Internet, and Arnav Aggrawal  wrote it more clearly. this The value complies with the following rules:

Use keywords when calling functions  new , and what is inside the function  this is a brand new object. If  the apply、call or  bind method is used to call or create a function, what is inside the function  this is the object passed into these methods as a parameter. When a function is called as a method on an object, what is inside the function  this is the object that called the function. For example, when  obj.method() called, the function inside  this will be bound to  obj the object. If the calling function does not comply with the above rules, then  this the value points to the global object ( global object). this The value  in browser context  points to window the object, but in strict mode ( 'use strict'), this the value of  undefined. If more than one of the above rules is met, the higher rule (number 1 is the highest, number 4 is the lowest) will determine  this the value. If the function is  ES2015 an arrow function, all rules above are ignored and this are set to the context in which it was created.

Tell me what you know about AMD and CommonJS.

They are all ways to implement a module system. Until  ES2015 their emergence, JavaScript there was no module system. CommonJS It is synchronous, while  AMD(Asynchronous Module Definition) it is obvious from the full name that it is asynchronous. CommonJS The design is for server-side development, and  AMD supports asynchronous loading of modules, which is more suitable for browsers.

The syntax I found  AMD is very verbose and CommonJS closer to  import the idiom of declaration statements in other languages. In most cases, I  AMD don't think it's necessary because if you  JavaScript bundle everything into one file, you won't get the benefits of asynchronous loading. In addition, CommonJS the syntax is closer to  Node the style of writing modules.  JavaScript When switching between front-end and back-end development, the context switching overhead is smaller.

I'm glad to see  ES2015 that the module loading scheme supports both synchronous and asynchronous, we can finally use only one scheme. While it's not fully rolled out to browsers yet  Node , we can use transcoding tools to convert it.

Please explain why the following code cannot be used as an IIFE: function foo(){ }();. What modifications need to be made to make it an IIFE?

IIFE (Immediately Invoked Function Expressions) stands for Immediately Invoked Function Expressions. JavaScript The parser will  function foo(){ }(); parse into  function foo(){ }和(); . Uncaught SyntaxError: Unexpected token ) Among them, the former is a function declaration; the latter (a pair of parentheses) is an error that is thrown when trying to call a function without specifying a name  .

The modification method is: add another pair of brackets, there are two forms: (function foo(){ })() and  (function foo(){ }()). The above function will not be exposed to the global scope. If you do not need to refer to itself within the function, you can omit the name of the function.

You may use  void the operator: void function foo(){ }();. However, this approach is problematic. The value of the expression is  undefined, so if yours  IIFE has a return value, don't use this approach. For example

const foo = void (function bar() {
  return 'foo';
})();

console.log(foo); // undefined

What is the difference between null, undefined and undeclared variables? How to check and judge these status values?

When you assign a value to a variable without using  var、let or  const declaring it in advance, the variable is an undeclared variable ( undeclared variables). Undeclared variables will leave the current scope and become variables defined in the global scope. In strict mode, assigning a value to an undeclared variable will throw  ReferenceError an error. Like using global variables, using undeclared variables is also a very bad practice and should be avoided whenever possible. To check them, you need to put the code that uses them in  try/catch a statement.

function foo() {
  x = 1; // 在严格模式下,抛出 ReferenceError 错误
}

foo();
console.log(x); // 1

When a variable has been declared but not assigned a value, the variable's value is  undefined. If the execution result of a function is assigned to a variable, but the function does not return any value, then the value of the variable is  undefined. To check it, use strict equality ( ===); alternatively  typeof, it returns  'undefined' a string. Note that you cannot use non-strict equality ( ==) to check because  nullusing non-strict equality will also return  if the variable value is true.

var foo;
console.log(foo); // undefined
console.log(foo === undefined); // true
console.log(typeof foo === 'undefined'); // true

console.log(foo == null); // true. 错误,不要使用非严格相等!

function bar() {}
var baz = bar();
console.log(baz); // undefined

null Can only be assigned to variables explicitly. It represents a null value, which is different from being explicitly assigned  undefined . To check the predicate  null value, use the strict equality operator. Note that, as before, you cannot use non-strict equality ( ==) to check, because  undefinedusing non-strict equality will also return  if the variable value is true.

var foo = null;
console.log(foo === null); // true

console.log(foo == undefined); // true. 错误,不要使用非严格相等!

As a personal habit, I never use undeclared variables. If variables are defined that are not used yet, I will explicitly assign values ​​to them after declaring them as null

What is a closure and why are we using it?

A closure is a combination of a function and the lexical environment in which the function is declared. The domain used in lexical scope is determined by where the variable is declared in the code. A closure is a function that can still access the scope of the outer (enclosing) function even if it is returned by the outer function.

Why use closures?

  • Use closures to privatize data or mock private methods. This approach is also called module mode ( module pattern).
  • Partial argument function ( partial applications) currying ( currying).

Please explain the main difference between .forEach loop and .map() loop. Under what circumstances are they used?

To understand the difference between the two, let’s look at what they do.

forEach

  • Iterate over the elements in an array.
  • Execute callback for each element.
  • No return value.
const a = [1, 2, 3];
const doubled = a.forEach((num, index) => {
  // 执行与 num、index 相关的代码
});

// doubled = undefined

map

  • Iterate over the elements in an array
  • A new array is created by "map" each element to a new element by calling a function on each element.
const a = [1, 2, 3];
const doubled = a.map((num) => {
  return num * 2;
});

// doubled = [2, 4, 6]

.forEach.map() The main difference between   and  is that .map() a new array is returned. If you want to get a result without changing the original array, use  .map(). If you only need to make iterative modifications on an array, use  forEach.

What are the typical application scenarios of anonymous functions?

Anonymous functions can be used in IIFEs to encapsulate code in the local scope so that the variables they declare are not exposed to the global scope.

(function () {
  // 一些代码。
})();

Anonymous functions can be used as callback functions that are used only once and do not need to be used elsewhere. When handler functions are defined inside the program that calls them, the code is more self-contained and readable, and the trouble of finding the location of the function body of the handler function is saved.

setTimeout(function () {
  console.log('Hello world!');
}, 1000);

Anonymous functions can be used in functional programming or Lodash (similar to callback functions).

const arr = [1, 2, 3];
const double = arr.map(function (el) {
  return el * 2;
});
console.log(double); // [2, 4, 6]

What is the difference between .call and .apply?

.call and are  .apply both used to call a function, the first parameter will be used as  this the value within the function. However, .call comma-separated arguments are accepted as the back arguments, while  .apply an array of arguments is accepted as the back arguments. A simple way to remember it is to associate the C call in it with comma separation ( comma-separated) and the A apply in it with arrays ( array).

function add(a, b) {
  return a + b;
}

console.log(add.call(null, 1, 2)); // 3
console.log(add.apply(null, [1, 2])); // 3

Please explain the usage of Function.prototype.bind.

Excerpted from MDN:

The bind() method creates a new function, and when called, sets its this keyword to the supplied value. When calling the new function, it provides a given sequence of arguments before any supply.

In my experience,  this it is very useful to bind a value into a method of a class that you want to pass to other functions. React This is often done in components

Please explain Ajax in as much detail as possible.

Ajax (asynchronous JavaScript and XML) is a Web development technology that uses many Web technologies on the client to create asynchronous Web applications. With Ajax, Web applications can send and retrieve data to and from the server asynchronously (in the background) without interfering with the display and behavior of existing pages. By separating the data exchange layer from the presentation layer, Ajax allows web pages and extended Web applications to dynamically change content without reloading the entire page. In fact, XML is now often replaced by JSON because of JavaScript's native support for JSON.

XMLHttpRequest API Often used for asynchronous communication. There are also recently popular ones  fetch API.

What are the advantages and disadvantages of using Ajax?

advantage
  • Better interactivity. New content from the server can be changed dynamically without reloading the entire page.
  • Reduces connections to the server since scripts and styles only need to be requested once.
  • Status can be maintained on a page. JavaScript variables and DOM state are maintained because the main container page is not reloaded.
  • Basically includes most of the advantages of SPA.
shortcoming
  • Dynamic web pages are difficult to collect.
  • Has no effect if JavaScript has been disabled in the browser.
  • Some web crawlers do not execute JavaScript and will not see content loaded by JavaScript.
  • Basically includes most of the shortcomings of SPA

Please explain how JSONP works and why is it not true Ajax?

JSONP (JSON with padding) is a method commonly used to bypass cross-domain restrictions in web browsers because Ajax does not allow cross-domain requests.

JSONP  <script> sends cross-domain requests via tags, typically using  callback query parameters such as: https://example.com?callback=printData. The server then wraps the data in a  printData function called and returns it to the client.

<!-- https://mydomain.com -->
<script>
  function printData(data) {
    console.log(`My name is ${data.name}!`);
  }
</script>

<script src="https://example.com?callback=printData"></script>
// 文件加载自 https://example.com?callback=printData
printData({name: 'Yang Shun'});

The client must have the function in its global scope  printData and the function will be executed by the client when a response is received from the cross-domain.

JSONP may have some security implications. Since JSONP is a pure JavaScript implementation, it can do everything JavaScript can do, so the provider of JSONP data needs to be trusted.

Nowadays, Cross-Origin Resource Sharing (CORS) is the recommended mainstream method, and JSONP has been regarded as a more hacky method.

Please explain variable hoisting.

Variable hoisting is a term used to explain the behavior of variable declarations in code. var Variables declared or initialized using  the keyword "raise" the declaration statement to the top of the current scope. However, only declarations will trigger hoisting, assignment statements (if any) will remain intact. Let's explain it with a few examples.

// 用 var 声明得到提升
console.log(foo); // undefined
var foo = 1;
console.log(foo); // 1

// 用 let/const 声明不会提升
console.log(bar); // ReferenceError: bar is not defined
let bar = 2;
console.log(bar); // 2

Function declarations hoist the function body, but function expressions (written in the form of variable declarations) only have variable declarations hoisted.

// 函数声明
console.log(foo); // [Function: foo]
foo(); // 'FOOOOO'
function foo() {
  console.log('FOOOOO');
}
console.log(foo); // [Function: foo]

// 函数表达式
console.log(bar); // undefined
bar(); // Uncaught TypeError: bar is not a function
var bar = function () {
  console.log('BARRRR');
};
console.log(bar); // [Function: bar]

Please describe event bubbling.

When an event fires on a DOM element, if there is an event listener, it will try to handle the event and then the event bubbles up to its parent element and the same thing happens. Finally until the event reaches the ancestor element. Event bubbling is the principle of implementing event delegation (event delegation).

What is the difference between == and ===

== is an abstract equality operator, === but a strict equality operator. == The operator performs necessary type conversions before comparison. === The operator does not perform type conversion, so if the two values ​​are not of the same type, they are returned directly  false . When used  == , some special things may happen, such as:

1 == '1'; // true
1 == [1]; // true
1 == true; // true
0 == ''; // true
0 == '0'; // true
0 == false; // true

My advice is to never use  == operators except for convenience   when comparing with null or  ,  which   will return   if   or undefineda == nullanullundefinedtrue

var a = null;
console.log(a == null); // true
console.log(a == undefined); // true

Front-end interview question bank ( essential for interviews) Recommended: ★★★★★            

Address: Front-end interview question bank

Please explain about JavaScript's Same Origin Policy.

The same-origin policy prevents JavaScript from making cross-origin requests. A source is defined as a combination of URI, hostname, and port number. This policy prevents malicious scripts on a page from accessing sensitive data on another web page through the page's Document Object Model.

How familiar are you with Promises and their polyfills?

Understand how it works. Promise Is an object that may produce a result at some time in the future: the result of a successful operation or the reason for its failure (for example, a network error occurred). Promise May be in one of three states: fulfilled, rejected or  pending. Users can  Promise add callback functions to handle the success of the operation or the reason for the failure.

Some common ones  polyfill are Polyfill  $.deferred, Q, and Bluebird, but not all polyfills are compliant with the specification. ES2015 supports Promises, and polyfills are generally not needed now.

What are the advantages and disadvantages of Promise instead of callback function?

advantage

  • Avoid unreadable callback hell.
  • Sequential asynchronous code written using .then() is simple and easy to read.
  • Writing parallel asynchronous code becomes easy with Promise.all().

shortcoming

  • Slightly increases the complexity of the code (this is debatable).
  • In older browsers that do not support ES2015, a polyfill needs to be introduced to use it.

Please explain the difference between synchronous and asynchronous functions.

Synchronous functions block, while asynchronous functions do not block. In a synchronous function, after the statement is completed, the next statement is executed. In this case, the program can be evaluated exactly in the order of statements, and if one of the statements takes a long time, the program's execution will stall for a long time.

Asynchronous functions usually accept a callback as a parameter and continue execution to the next line immediately after calling the asynchronous function. The callback function is only called when the asynchronous operation completes and the call stack is empty. Heavy load operations such as loading data from a web server or querying a database should be completed asynchronously so that the main thread can continue to perform other operations without blocking until the time-consuming operation completes (in the browser, the interface will freeze) .

What is an event loop? What is the difference between call stack and task queue?

The event loop is a single-threaded loop that monitors the call stack and checks if any work is about to be completed in the task queue. If the call stack is empty and there is a callback function in the task queue, the callback function is dequeued and pushed into the call stack for execution.

What is the difference between creating variables using let, var and const?

The scope of a variable declared with  var is its current execution context, which can be a nested function or a variable declared outside any function. let and  const are block-scoped, meaning they can only be accessed within the nearest set of curly braces (in a function, if-else block, or for loop).

function foo() {
  // 所有变量在函数中都可访问
  var bar = 'bar';
  let baz = 'baz';
  const qux = 'qux';

  console.log(bar); // bar
  console.log(baz); // baz
  console.log(qux); // qux
}

console.log(bar); // ReferenceError: bar is not defined
console.log(baz); // ReferenceError: baz is not defined
console.log(qux); // ReferenceError: qux is not defined
if (true) {
  var bar = 'bar';
  let baz = 'baz';
  const qux = 'qux';
}

// 用 var 声明的变量在函数作用域上都可访问
console.log(bar); // bar
// let 和 const 定义的变量在它们被定义的语句块之外不可访问
console.log(baz); // ReferenceError: baz is not defined
console.log(qux); // ReferenceError: qux is not defined

var Will hoist the variable, which means the variable can be used before it is declared. letand  const will not promote the variable, and an error will be reported if used in advance.

console.log(foo); // undefined

var foo = 'foo';

console.log(baz); // ReferenceError: can't access lexical declaration 'baz' before initialization

let baz = 'baz';

console.log(bar); // ReferenceError: can't access lexical declaration 'bar' before initialization

const bar = 'bar';

No error will be reported with  var repeated statements, but  let it  const will.

var foo = 'foo';
var foo = 'bar';
console.log(foo); // "bar"

let baz = 'baz';
let baz = 'qux'; // Uncaught SyntaxError: Identifier 'baz' has already been declared

letconst The difference between  and  is that let multiple assignments are allowed, but  const only one is allowed.

// 这样不会报错。
let foo = 'foo';
foo = 'bar';

// 这样会报错。
const baz = 'baz';
baz = 'qux';

Front-end interview question bank ( essential for interviews) Recommended: ★★★★★            

Address: Front-end interview question bank

Can you give an example of using an arrow function and how it differs from other functions

An obvious advantage is that arrow functions can simplify the syntax of creating functions. We do not need to add  function keywords in front of arrow functions. And arrow functions  this are automatically bound to the context of the current scope, which is different from ordinary functions. The value of a normal function  this can only be determined when it is executed. This feature of arrow functions is particularly useful for callback functions, especially for  React components.

What is the definition of higher-order function?

A higher-order function is a function that takes one or more functions as parameters, is used for data processing, and may also return a function as a result. Higher-order functions are used to abstract repetitive operations. A typical example is  mapthat it takes an array and a function as parameters. map Use this function to convert each element in an array and return a new array containing the converted elements. Other common examples in JavaScript are  forEach, filter and  reduce. Higher-order functions are not only used when you need to operate arrays, but there are also many use cases where functions return new functions. Function.prototype.bind Just an example.

Map example

Suppose we have an array of names and we need to convert each character to uppercase.

const names = ['irish', 'daisy', 'anna'];

The method without using higher-order functions is this:

const transformNamesToUppercase = function (names) {
  const results = [];
  for (let i = 0; i < names.length; i++) {
    results.push(names[i].toUpperCase());
  }
  return results;
};
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']

Use  .map(transformerFn) to make code more concise

const transformNamesToUppercase = function (names) {
  return names.map((name) => name.toUpperCase());
};
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']

Please give an example of destructuring an object or array.

Destructuring is a new feature in ES6, which provides a concise and convenient way to extract the values ​​​​of an object or array and put them into different variables.

Array destructuring

// 变量赋值
const foo = ['one', 'two', 'three'];

const [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"
// 变量交换
let a = 1;
let b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

Object destructuring

// 变量赋值
const o = {p: 42, q: true};
const {p, q} = o;

console.log(p); // 42
console.log(q); // true

Can you give an example of a curry function? What are its benefits?

Currying is a pattern in which a function with multiple arguments is broken into multiple functions that, when called in series, accumulate all required arguments one at a time. This technique helps write functional style code, making the code more readable and compact. It's worth noting that for a function to be curryed, it needs to start with a function and then break it down into a series of functions, each of which takes a parameter.

function curry(fn) {
  if (fn.length === 0) {
    return fn;
  }

  function _curried(depth, args) {
    return function (newArgument) {
      if (depth - 1 === 0) {
        return fn(...args, newArgument);
      }
      return _curried(depth - 1, [...args, newArgument]);
    };
  }

  return _curried(fn.length, []);
}

function add(a, b) {
  return a + b;
}

var curriedAdd = curry(add);
var addFive = curriedAdd(5);

var result = [0, 1, 2, 3, 4, 5].map(addFive); // [5, 6, 7, 8, 9, 10]

Front-end interview question bank ( essential for interviews) Recommended: ★★★★★            

Address: Front-end interview question bank

 My cousin made her own five-star red flag National Day avatar with just one click. It’s super nice.

Guess you like

Origin blog.csdn.net/weixin_42981560/article/details/133318169