• 2023年最新JavaScript前端面试题汇总
  • 发布于 2个月前
  • 533 热度
    0 评论

2023年对于程序员来说是个艰难的一年,裁员潮从大西洋海岸的硅谷一直刮到了太平洋海岸的BAT巨头。大量被裁人员的疯狂涌入也让2023年的金三银四招聘季不再像往年那么熠熠生辉。作为前端开发者的我们,有躺平资本的可以选择躺平,没躺平资本的只能选择卷。今天我汇总了2023年最新的前端面试题,希望对于只能加入内卷行列的前端开发有所帮助。


那我们现在就开始今天的内容吧。
1.什么是JavaScript?
JavaScript 是一种客户端/服务器端编程语言。可以将 JavaScript 插入到 HTML 中,使网页具有交互性并使用户参与。
2. JavaScript 中的hoisting是什么?
hoisting意味着所有的声明都被移动到范围的顶部,这发生在代码运行之前。
对于函数,这意味着您可以从范围内的任何地方调用它们,甚至在它们被定义之前。
hello();  // Prints "Hello world! " even though the function is called "before" declaration

function hello(){ 
  console.log("Hello world! ");
}
对于变量,hoisting有点不同,它在定义变量范围之前,它们为 undefined 。
例如,在定义变量之前调用它:
console.log(dog);
var dog = "Spot";
结果是:
undefined
这可能会令人惊讶,因为您可能预计它会导致错误。如果你声明一个函数或变量,无论你在哪里声明它,它总是被移动到范围的顶部。

3. isNan() 函数有什么作用?
您可以使用 isNan() 函数来检查值的类型是否为数字且为 NaN。(是的,NaN 是数字类型,尽管它的名称是“非数字”。这是因为它是底层的数字类型,即使它没有数值。)

例如:
/* 堆代码 duidaima.com */
function toPounds(kilos) {
  if (isNaN(kilos)) {
    return 'Not a Number! Cannot be a weight.';
  }
  return kilos * 2.2;
}

console.log(toPounds('this is a test'));
console.log(toPounds('100'));
输出:
Not a Number! Cannot be a weight.
220.00000000000003
4. JavaScript 中的负无穷大是什么?
如果在 JavaScript 中将负数除以零,则会得到负无穷大。
例如:
console.log(-10/0)
输出:
-Infinity
5. 什么是未声明变量?未定义的变量怎么样?
程序中根本不存在未声明的变量。如果您的程序试图读取未声明的变量,则会引发运行时错误。
调用未声明变量的示例显然会导致错误:
console.log(dog);
输出:
error: Uncaught ReferenceError: dog is not defined
未定义的变量在程序中声明但没有值。如果程序尝试读取未定义的变量,则会返回未定义的值并且应用程序不会崩溃。
未定义变量的示例是:
let car;
console.log(car);
输出:
undefined
6. JavaScript 中有哪几种弹出框?
弹窗的三种类型有警告、确认和提示。让我们看一下每个的使用示例:
01).警告
例如:
window.alert("Hello, world!");
02).确认
例如:
if (window.confirm("Are you sure you want to go?")) {
  window.open("exit.html", "See you again!");
}
03).提示
例如:
let person = window.prompt("Enter your name");
if (person != null) {
  console.log('Hello', person);
}
7. == 和 === 有什么区别?
== 比较值
=== 比较值和类型
例子:
var x = 100;
var y = "100";
(x == y)  // --> true because the value of x and y are the same
(x === y) // --> false because the type of x is "number" and type of y is "string"
8. 隐式类型强制有什么作用?举个例子。
隐式类型强制意味着一个值在幕后从一种类型转换为另一种类型。当表达式的操作数属于不同类型时,就会发生这种情况。
例如,字符串强制转换意味着在数字上应用 + 运算符,字符串会自动将数字转换为字符串。
例如:
var x = 1;
var y = "2";

x + y // Returns "12"
但是在处理减法时,强制以另一种方式起作用。它将字符串转换为数字。
例如:
var x = 10;
var y = "10";

x - y // Returns 0
9. JavaScript 是静态类型语言还是动态类型语言?这是什么意思?
JavaScript 是动态类型的。这意味着在运行时检查对象的类型。(在静态类型语言中,类型在编译时检查。)换句话说,JavaScript 变量与类型无关,这意味着您可以毫无问题地更改数据类型。
var num = 10;
num = "Test";
在静态类型语言(如 C++)中,不可能以这种方式将整数更改为字符串。
10. JavaScript 中的 NaN 是什么?
NaN 的意思是“非数字”,这意味着在 JavaScript 中不是正式数字的值。可能令人困惑的是,使用 typeof() 函数对 NaN 进行类型检查会导致 Number。
console.log(typeof(NaN))
输出:
Number
为避免混淆,请使用 isNaN() 来检查值的类型是 NaN 还是非数字。

11. JavaScript 中的展开运算符是什么?
扩展运算符允许将可迭代对象(数组/对象/字符串)扩展为单个参数/元素。让我们举个例子来看看这个行为,
function sum(a, b, c) {
  return a + b + c;
}
const nums = [15, 25, 35];
console.log(sum(...nums));
输出:
75
12. JavaScript 中的闭包是什么?
JavaScript 中的闭包意味着内部函数可以访问外部函数的变量——即使在外部函数返回之后。例如,要创建一个自增 1 的计数器,您可以使用闭包:
/* 堆代码 duidaima.com */
function createCounter() {
   let counter = 0;
   function increment() {
     counter++;
     console.log(counter);
   }
   return increment;
}
这里 createCounter() 是外部函数, increment() 是内部函数。现在您可以按如下方式使用它:
const add = createCounter();
add();
add();
add();
输出
1
2
3
这是有效的,因为存储内部函数 increment() 的 add 仍然可以访问 createCounter() 函数的计数器变量。这是可能的,因为 JavaScript 的闭包特性:即使在外部函数返回后,内部函数也可以访问外部函数的变量。

13. JavaScript 中如何处理异常?
如果表达式抛出错误,您可以使用 try...catch 语句处理它们。使用此结构的想法是尝试运行一个表达式,例如带有输入的函数,并捕获可能的错误。
例如:
function weekDay(dayNum) {
  if (dayNum < 1 || dayNum > 7) {
    throw 'InvalidDayNumber'
  } else {
    return ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][dayNum - 1];
  }
}

try { // Try to run the following
  let day = weekDay(8);
  console.log(day);
}
catch (e) { // catch an error if the above try failed
  let day = 'unknown';
  console.log(e);
}
14. 什么是网络存储?
Web 存储是一种 API,它为浏览器提供了一种将键值对存储到用户浏览器本地的方法。使用网络存储使这个过程比使用 cookie 更直观。
Web 存储提供了两种存储数据的方式:
本地存储——为客户端存储没有过期日期的数据。
会话存储——只存储一个会话的数据,浏览器关闭时数据消失。

以下是如何从 sessionStorage 保存、访问和删除项目的示例:
// 堆代码 duidaima.com
// Save data to sessionStorage
sessionStorage.setItem('favoriteColor', 'gray');

// Get the color from the sessionStorage
let data = sessionStorage.getItem('favoriteColor');
console.log(data);

// Remove saved color preset from sessionStorage
sessionStorage.removeItem('favoriteColor');

// Remove ALL the saved data from sessionStorage
sessionStorage.clear();
以下是使用 localStorage 执行相同操作的方法:
// Save data to localStorage
localStorage.setItem('favoriteColor', 'gray');

// Get the color from the localStorage
let data = localStorage.getItem('favoriteColor');
console.log(data);

// Remove saved color preset from localStorage
localStorage.removeItem('favoriteColor');

// Remove ALL the saved data from localStorage
localStorage.clear();
15. 为什么需要网络存储?
Web 存储(问题 14)使得在本地存储大量数据成为可能。关键是它不会影响网站的性能。使用网络存储,信息不会存储到服务器中。与 cookie 相比,这使其成为一种更可取的方法。

16.什么是模块?
模块是可重用代码的单元。通常,您可以从模块中将有用的函数或构造函数导入到您的项目中。
从模块导入功能可能如下所示:
import { hello } from './modules/helloWorld.js';
17. JavaScript 中的“作用域”是什么意思?
范围定义了“代码的可见性”。更正式地说,范围描述了变量、函数和其他对象在代码中的哪些位置可以访问。范围是在运行时在您的代码中创建的。
例如,块作用域表示花括号之间的“区域”:
if(true) {
   let word = "Hello";
}
console.log(word); // ERROR OCCURS
在这里,除了在 if 语句中,不能从其他任何地方访问变量 word。

18. JavaScript 中的高阶函数是什么?
高阶函数对另一个函数进行操作。它要么接受一个函数作为参数,要么返回另一个函数。
例如:
function runThis(inputFunction) {
  inputFunction();
}

runThis(function() { console.log("Hello world") });
输出
Hello
world
另外一个例子:
function giveFunction() {
  return function() {
    console.log("Hello world")
  }
}

var action = giveFunction();
action()
输出:
Hello world
19. JavaScript 中的“this”关键字是什么?
这是指对象本身。
例如:
var student = {
    name:  "Matt",
    getName: function(){
      console.log(this.name);
    }
}

student.getName();
输出:
Matt
要使 getName() 方法在student对象中起作用,该对象必须访问它自己的属性。这可以通过对象内的 this 关键字来实现。

20. call()方法有什么作用?
call() 方法可用于在另一个对象上调用一个对象的方法。
obj1.func.call(obj2)
例子:
var student = {
  name: "Matt",
  getName: function(){
    console.log(this.name);
  }
}

var anotherStudent = {
  name: "Sophie"
};

student.getName.call(anotherStudent);
输出:
Sofie
Call() 方法也可用于通过指定所有者对象来调用函数。
例如:
function sayHi(){
  console.log("Hello " + this.name);
}

var person = {name: "Matt"};

sayHi.call(person);
输出:
Hello Matt
call() 也可以接受参数。
例如:
function sayHi(adjective){
  console.log("Hello " + this.name + ", You are " + adjective);
}

var obj = {name: "Matt"};
sayHi.call(obj, "awesome");
输出:
Hello Matt, you are awesome
21.什么是apply()方法?
apply() 方法与 call() 方法的作用相同,不同之处在于 apply() 方法接受参数作为数组。
例如:
const person = {
    name: 'John'
}

function greet(greeting, message) {
    return `${greeting} ${this.name}. ${message}`;
}

let result = greet.apply(person, ['Hello', 'How are you?']);

console.log(result);
输出:
Hello John. How are you?
在行中:
let result = greet.apply(person, ['Hello', 'How are you?']);
在 greet() 函数中,“Hello”被分配给问候语,“How are you?”被分配给消息。

22.什么是bind()方法?
bind() 方法返回一个新函数,其 this 已设置为另一个对象。与 apply() 和 call() 不同,bind() 不会立即执行函数。相反,它返回一个新版本的函数,其 this 被设置为另一个值。
让我们看一个例子:
let person = {
    name: 'John',
    getName: function() {
        console.log(this.name);
    }
};

window.setTimeout(person.getName, 1000);
这不会打印名称“John”,而是打印 undefined。要理解为什么会发生这种情况,请以等效方式重写最后一行:
let func = person.getName;
setTimeout(func, 1000);
setTimeout() 接收与人对象分开的函数,但没有人的名字。因此,当 setTimeout() 调用 person.getName 时,名称是未定义的。要解决此问题,您需要将 getName() 方法绑定到 person 对象:
let func = person.getName.bind(person);
setTimeout(func, 1000);
输出:
John
让我们检查一下这种方法是如何工作的:
person.getName 方法绑定到 person 对象。
绑定函数 func 现在将 this 值设置为 person 对象。当您将这个新的绑定函数传递给 setTimeout() 函数时,它知道如何获取此人的姓名。

23.什么是柯里化?
柯里化意味着将具有 n 个参数的函数转换为具有一个或更少参数的 n 个函数。例如,假设您有一个函数 add() 可以对两个数字求和:
function add(a, b) {
    return a + b;
}
您可以通过以下方式调用此函数:
add(2,3)
然后让我们柯里化函数:
function add(a) {
  return function(b) {
    return a + b;
  }
}
现在您可以通过以下方式调用此柯里化函数:
add(2)(3)
柯里化不会改变函数的行为,它改变了它被调用的方式。
24. 什么是 JavaScript 中的承诺?
Promise 是一个对象,它可能在未来产生一个值。承诺总是处于可能的状态之一:已履行、已拒绝或未决。
创建承诺如下所示:
const promise = new Promise(function(resolve, reject) {
    // implement the promise here
})
例如,让我们创建一个在被调用两秒后解析的承诺。
const promise = new Promise(resolve => {
  setTimeout(() => {
    resolve("Hello, world!");
  }, 2000);
}, reject => {});
现在 promises 的关键是您可以在使用 .then() 方法解析 promise 后立即执行代码:
promise.then(result => console.log(result));
输出:
Hello, world!
Promise 可以链接在一起,以便已解决的 promise 返回一个新的 promise。下面是 promise 的流程图,也说明了如何将它们链接起来:

25. 为什么要使用promises?
在 JavaScript 中,promises 对于异步操作很有用。
过去,必须使用回调来处理异步操作,即使用在操作完成后立即执行的函数。这导致了“回调地狱”,一个带有嵌套回调的金字塔形代码。

Promises 通过减少回调地狱和编写更清晰的代码,为回调提供了另一种方法。这是可能的,因为 promise 可以按以下方式链接:

26. JavaScript 中的回调函数是什么?
回调函数是作为参数传递给另一个函数的函数。当某些动作完成时,此函数在传递给它的函数内部执行以“回调”。
让我们看一个例子:

function greetName(name) {
  console.log('Hello ' + name);
}

function askName(callback) {
  let name = prompt('Enter your name.');
  callback(name);
}

askName(greetName);
此代码会提示您输入姓名,当您输入姓名时,它会对该姓名说“你好”。因此,回调函数(在本例中为 greetName)仅在您输入名称后执行。

27. 为什么在 JavaScript 中使用回调?
回调很有用,因为 JavaScript 是一种事件驱动的语言。换句话说,它不是等待响应,而是在监听其他事件的同时继续执行。
上面的例子展示了回调在 JavaScript 中的用处:
function greetName(name) {
  console.log('Hello ' + name);
}

function askName(callback) {
  let name = prompt('Enter your name.');
  callback(name);
}

askName(greetName);
28. 什么是 JavaScript 中的严格模式?
严格模式允许您将程序设置为在严格的上下文中运行。这可以防止执行某些操作。此外,还会抛出更多异常。表达“使用严格”;告诉浏览器启用严格模式。
例如:
"use strict";
number = 1000;
这会导致错误,因为严格模式会阻止您为未声明的变量赋值。

29.什么是立即调用函数?
立即调用函数 (IIFE) 在定义后立即运行。
例如:
(function(){ 
  // action here
})();
要了解 IIFE 的工作原理,请查看它周围的括号:当 JavaScript 看到关键字 function 时,它假设有一个函数声明来了。但是上面的声明是无效的,因为函数没有名字。为了解决这个问题,使用了声明周围的第一组括号,这告诉解释器这是一个函数表达式,而不是声明。
(function (){
   // action here;
})
然后,要调用该函数,需要在函数声明的末尾添加另一组括号,这类似于调用任何其他函数:
(function (){
  // action here
})();
30. 什么是cookie?
Cookie 是存储在您计算机上的一个小数据包。例如,网站可以在访问者的浏览器上放置 cookie,以便在用户下次访问该页面时记住登录凭据。在幕后,cookie 是带有键值对的文本文件。要创建、读取或删除 cookie,请使用 document.cookie 属性。例如,让我们创建一个保存用户名的 cookie:
document.cookie = "username=foobar123";
31. 为什么要在 JavaScript 中使用严格模式?
严格模式有助于编写“安全”的 JavaScript 代码。这意味着错误的语法实践会转化为真正的错误。例如,严格模式会阻止创建全局变量。要声明严格模式,请添加“use strict”;在你想处于严格模式下的语句之前的语句:
'use strict';
const sentence = "Hello, this is very strict";
32.双感叹号有什么作用?
双感叹号将任何东西转换为 JavaScript 中的布尔值。
!!true    // true
!!2       // true
!![]      // true
!!"Test"  // true

!!false   // false
!!0       // false
!!""      // false
这是可行的,因为 JavaScript 中的任何东西本质上都是“Truthy”或“Falsy”。

33. 如何删除属性及其值?
您可以使用 delete 关键字从对象中删除属性及其值。
让我们看一个例子:
var student = {name: "John", age:20};
delete student.age;

console.log(student);
输出:
{name: "John"}
34. 如何检查 JavaScript 中变量的类型?
使用 typeof 运算符。
typeof "John Abraham"  // Returns "string"
typeof 100             // Returns "number"
35. JavaScript 中的 null 是什么?
null 表示没有值,它突出显示变量不指向任何对象。
null 的类型是一个对象:
var name = null;
console.log(typeof(name))
36. Null 与 undefined的区别
Null
1.是一个值,表示变量不指向任何对象。
2.是对象类型。
3.表示 null、空或不存在的引用。
4.表示缺少变量值。
5.使用原始操作转换为 0。
Undefined
1.是一个值,表示已声明但没有值的变量
2.类型未定义。
3.表示变量不存在。
4.使用原始操作转换为 NaN。


37. 你能用 JavaScript 访问历史记录吗?
这是可以的,您可以通过包含浏览器历史记录的 window.history 访问历史记录。要检索上一个和下一个 URL,可以使用以下方法:

window.history.back()
window.history.forward()
38.什么是全局变量?
全局变量在代码中随处可用。要创建全局变量,请省略 var 关键字:
x = 100; // Creates a global variable.
此外,如果在任何函数之外使用 var 创建变量,则会创建一个全局变量。

39. JavaScript 与 Java 有关系吗?
没有关系。它们是两种不同的编程语言,彼此之间没有任何关系。

40. 什么是 JavaScript 事件?
事件是 HTML 元素发生的事情。当在 HTML 页面中使用 JavaScript 时,它可以对事件做出反应,例如,单击按钮。让我们创建一个 HTML 页面,其中有一个按钮,当该按钮被单击时,会出现一个警告:
<!doctype html>

<html>
 <head>
 <title>堆代码- duidaima.com </title>
   <script>
     function sayHi() {
       alert('Hi, how are you?');
     }
</script>
 </head>

 <body>
   <button type="button" onclick="sayHi()">Click here</button>
 </body>

</html>
41. preventDefault() 方法有什么作用?
preventDefault() 取消一个方法。名称 preventDefault 很好地描述了这种行为。它阻止事件采用默认行为。
例如,您可以在单击提交按钮时阻止表单提交:
document.getElementById("link").addEventListener("click", function(event){
  event.preventDefault()
});
42.什么是setTimeout()方法?
setTimeout() 方法在指定的毫秒数后调用一个函数(一次)。例如,让我们在一秒(1000 毫秒)后记录一条消息:
setTimeout(function() {
    console.log("Good day");
}, 1000);
43.什么是setInterval()方法?
setInterval() 方法以自定义间隔定期调用函数。例如,让我们每秒定期记录一条消息:
setInterval(function() {
    console.log("Good day");
}, 1000);
44. 什么是 ECMAScript?
ECMAScript 是构成 JavaScript 基础的脚本语言。
ECMAScript 由 ECMA 国际标准组织标准化(查看 ECMA-262 和 ECMA-402 规范)。

45.什么是JSON?
JSON(JavaScript Object Notation)是一种用于交换数据的轻量级数据格式。
例如,这是一个 JSON 对象:
{
    'name': 'Matt',
    'address': 'Imaginary Road 22',
    'age': 32,
    'married': false,
    'hobbies': ['Jogging', 'Tennis', 'Padel']
}
JSON 的语法规则是:
.数据以键值对的形式存在。
.数据以逗号分隔。
.大括号定义一个对象。
.方括号定义一个数组。
46.JSON用在什么地方?
当向服务器发送数据和向服务器发送数据时,数据必须是文本格式。JSON 是一种纯文本格式,允许将数据发送到服务器以及从服务器向浏览器发送数据。几乎所有编程语言都支持 JSON,因此它也可以与其他语言一起使用。

47. 为什么要使用JSON stringify?
当您向服务器发送数据时,它必须是一个字符串。要将 JavaScript 对象转换为字符串,可以使用 JSON.stringify() 方法。
var dataJSON = {name: "Matt", age: 51};
var dataString = JSON.stringify(dataJSON);
console.log(dataString);
输出:
'{"name":"Matt","age":51}'

48. 如何将 JSON 字符串转换为 JSON 对象?

当您从服务器接收数据时,它始终是字符串格式。要将 JSON 字符串转换为 JavaScript 对象,请使用 JSON.parse() 方法。

var data = '{"name":"Matt", "age":51}';
var dataJSON = JSON.parse(data);
console.log(dataJSON);
输出:

{
    name:"Matt",
    age:51
}
49. 如何为变量分配默认值?
使用逻辑运算符 || 在分配中提供默认值。
const a = b || c;
这使得如果 b 是假的,那么 c 将被分配给 a。(Falsy 表示 null、false、undefined、0、空字符串或 NaN。)

50. 你能为函数定义属性吗?
是的,因为函数也是对象。
让我们看一个例子:
let func = function(x) {

};
func.property1 = "Hello there";
console.log(func.property1);
输出:
Hello there

总结
到这里,这50道JavaScript前端面试题的就结束了,希望这些知识能够帮助您提升学习效率。

用户评论