当前位置: 首页 > news >正文

Javascript面试题及详细答案150道(046-060)

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux… 。

前后端面试题-专栏总目录

在这里插入图片描述

文章目录

  • 一、本文面试题目录
      • 46. 如何实现对象的深拷贝(考虑多种数据类型)?
      • 47. 什么是模块化?CommonJS和ES6 Module有什么区别?
      • 48. 如何判断两个对象是否相等(深相等)?
      • 49. 什么是事件委托(事件代理)?有什么好处?
      • 50. 如何阻止事件冒泡和默认行为?
      • 51. 什么是变量提升和函数提升?
      • 52. 什么是JSON?JSON和JavaScript对象有什么区别?
      • 53. 如何获取当前时间并格式化?
      • 54. 什么是递归函数?使用递归要注意什么?
      • 55. 如何实现数组的findIndex方法?
      • 56. 什么是Set和Map?它们有什么特点?
      • 57. 如何实现数组的filter方法?
      • 58. 什么是严格模式(strict mode)?如何启用?有什么限制?
      • 59. 什么是迭代器(Iterator)?它有什么作用?
      • 60. 如何实现数组的reduce方法?
  • 二、150道面试题目录列表

一、本文面试题目录

46. 如何实现对象的深拷贝(考虑多种数据类型)?

实现一个能处理多种数据类型(对象、数组、日期、正则等)的深拷贝函数:

function deepClone(obj, hash = new WeakMap()) {if (obj === null || typeof obj!== 'object') return obj;if (hash.has(obj)) return hash.get(obj); // 处理循环引用let cloneObj;// 处理日期if (obj instanceof Date) {cloneObj = new Date(obj);hash.set(obj, cloneObj);return cloneObj;}// 处理正则if (obj instanceof RegExp) {cloneObj = new RegExp(obj.source, obj.flags);hash.set(obj, cloneObj);return cloneObj;}// 处理数组和对象cloneObj = Array.isArray(obj)? [] : {};hash.set(obj, cloneObj);// 递归拷贝属性Reflect.ownKeys(obj).forEach(key => {cloneObj[key] = deepClone(obj[key], hash);});return cloneObj;
}

47. 什么是模块化?CommonJS和ES6 Module有什么区别?

模块化是将代码拆分为独立的模块,便于复用和维护。
区别:

  • 语法:CommonJS用require()导入、module.exports导出;ES6 Module用import导入、export导出。
  • 加载方式:CommonJS是运行时加载(动态),ES6 Module是编译时加载(静态)。
  • 作用域:CommonJS模块中,模块是一个函数作用域;ES6 Module是块级作用域。
  • this指向:CommonJS模块中this指向当前模块;ES6 Module中this是undefined。

示例:

// CommonJS
const moduleA = require('./moduleA');
module.exports = { foo: 'bar' };// ES6 Module
import { moduleB } from './moduleB';
export const baz = 'baz';

48. 如何判断两个对象是否相等(深相等)?

深相等是指两个对象的所有层级属性都相等。实现方法:

function deepEqual(a, b) {// 基本类型直接比较if (a === b) return true;// 处理nullif (a === null || b === null) return false;// 类型不同返回falseif (typeof a!== typeof b) return false;// 处理对象和数组if (typeof a === 'object') {// 获取属性名const keysA = Reflect.ownKeys(a);const keysB = Reflect.ownKeys(b);if (keysA.length!== keysB.length) return false;// 递归比较每个属性return keysA.every(key => deepEqual(a[key], b[key]));}return false;
}

49. 什么是事件委托(事件代理)?有什么好处?

事件委托是将子元素的事件处理委托给父元素,利用事件冒泡原理,当子元素触发事件时,父元素能捕获到并处理。
好处:

  • 减少事件监听器数量,提高性能。
  • 动态添加的子元素也能触发事件,无需重新绑定。

示例代码:

// 父元素ul代理li的点击事件
const ul = document.querySelector('ul');
ul.addEventListener('click', (e) => {if (e.target.tagName === 'LI') { // 判断触发事件的是liconsole.log('点击了li:', e.target.textContent);}
});

50. 如何阻止事件冒泡和默认行为?

  • 阻止事件冒泡:
    • 标准浏览器:event.stopPropagation()
    • IE低版本:event.cancelBubble = true
  • 阻止默认行为(如表单提交、链接跳转):
    • 标准浏览器:event.preventDefault()
    • IE低版本:event.returnValue = false
    • 也可在事件处理函数中返回false(仅适用于部分事件,如onclick)。

示例代码:

document.getElementById('btn').addEventListener('click', (e) => {e.stopPropagation(); // 阻止冒泡e.preventDefault(); // 阻止默认行为(若按钮有默认行为)
});

51. 什么是变量提升和函数提升?

  • 变量提升:使用var声明的变量,会被提升到作用域顶部,声明提升但赋值不提升。
  • 函数提升:函数声明会被整体提升到作用域顶部,可在声明前调用。函数表达式(如var fn = function(){})只有变量提升,没有函数提升。

示例代码:

// 变量提升
console.log(x); // undefined(var声明提升,赋值未提升)
var x = 10;// 函数提升
foo(); // 能调用,函数声明提升
function foo() {console.log('foo');
}// 函数表达式不提升
bar(); // 报错,bar是变量,此时值为undefined
var bar = function() {console.log('bar');
};

52. 什么是JSON?JSON和JavaScript对象有什么区别?

JSON(JavaScript Object Notation)是一种轻量级数据交换格式,基于JavaScript对象字面量语法,但有严格规定。
区别:

  • JSON是字符串,用于数据传输;JavaScript对象是内存中的数据结构。
  • JSON的键必须用双引号包裹;JavaScript对象的键可不用引号或用单/双引号。
  • JSON的值不能有函数、undefined、Symbol;JavaScript对象可以。
  • JSON的尾逗号不允许;JavaScript对象允许。

示例:

// JSON
{ "name": "Jack", "age": 25 }
// JavaScript对象
const obj = { name: 'Jack', age: 25, sayHi() {} };

53. 如何获取当前时间并格式化?

可使用Date对象获取当前时间,然后自定义格式化函数。

示例代码:

function formatDate(date = new Date(), format = 'yyyy-MM-dd HH:mm:ss') {const year = date.getFullYear();const month = String(date.getMonth() + 1).padStart(2, '0');const day = String(date.getDate()).padStart(2, '0');const hours = String(date.getHours()).padStart(2, '0');const minutes = String(date.getMinutes()).padStart(2, '0');const seconds = String(date.getSeconds()).padStart(2, '0');return format.replace('yyyy', year).replace('MM', month).replace('dd', day).replace('HH', hours).replace('mm', minutes).replace('ss', seconds);
}
console.log(formatDate()); // 2025-07-21 10:30:45(当前时间)

54. 什么是递归函数?使用递归要注意什么?

递归函数是在函数内部调用自身的函数,用于解决可分解为相同子问题的问题(如阶乘、斐波那契数列)。
注意:

  • 必须有终止条件,否则会导致栈溢出。
  • 递归深度不宜过深,可能影响性能。

示例代码:

// 计算阶乘
function factorial(n) {if (n === 1) return 1; // 终止条件return n * factorial(n - 1);
}
console.log(factorial(5)); // 120

55. 如何实现数组的findIndex方法?

findIndex()返回数组中满足条件的第一个元素的索引,若没有则返回-1。

示例代码:

Array.prototype.myFindIndex = function(callback, thisArg) {for (let i = 0; i < this.length; i++) {if (callback.call(thisArg, this[i], i, this)) {return i;}}return -1;
};
const arr = [10, 20, 30];
console.log(arr.myFindIndex(item => item > 15)); // 1

56. 什么是Set和Map?它们有什么特点?

  • Set:是值的集合,特点是值唯一,没有重复值,可用于数组去重。
    常用方法:add()、delete()、has()、clear()、size属性。
  • Map:是键值对的集合,键可以是任意类型(对象、基本类型等),与对象不同,对象的键只能是字符串或Symbol。
    常用方法:set()、get()、delete()、has()、clear()、size属性。

示例代码:

// Set
const set = new Set([1, 2, 2, 3]);
console.log(set.size); // 3
set.add(4);
console.log(set.has(2)); // true// Map
const map = new Map();
const key = { id: 1 };
map.set(key, 'value');
console.log(map.get(key)); // value

57. 如何实现数组的filter方法?

filter()创建一个新数组,包含所有通过测试(回调函数返回true)的元素。

示例代码:

Array.prototype.myFilter = function(callback, thisArg) {const result = [];for (let i = 0; i < this.length; i++) {if (callback.call(thisArg, this[i], i, this)) {result.push(this[i]);}}return result;
};
const arr = [1, 2, 3, 4, 5];
console.log(arr.myFilter(item => item % 2 === 0)); // [2, 4]

58. 什么是严格模式(strict mode)?如何启用?有什么限制?

严格模式是JavaScript的一种限制性更强的执行模式,使代码更规范、更安全。
启用:在脚本或函数顶部添加'use strict';
限制:

  • 变量必须声明后使用。
  • 不能删除变量、函数或函数参数。
  • 禁止this指向全局对象(普通函数调用时this为undefined)。
  • 禁止在函数内部声明eval和arguments为变量。

示例代码:

'use strict';
// x = 10; // 报错,变量未声明
function strictFunc() {'use strict';console.log(this); // undefined(普通调用时)
}
strictFunc();

59. 什么是迭代器(Iterator)?它有什么作用?

迭代器是一种接口,为各种数据结构提供统一的遍历方式,任何实现了Iterator接口的数据结构都可被for…of循环遍历。
迭代器有一个next()方法,返回一个包含value(当前值)和done(是否遍历结束)的对象。
作用:使不同数据结构(数组、Set、Map等)的遍历方式统一。

示例代码:

const arr = [1, 2, 3];
const iterator = arr[Symbol.iterator]();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

60. 如何实现数组的reduce方法?

reduce()对数组中的每个元素执行回调函数,将其缩减为单个值,可指定初始值。

示例代码:

Array.prototype.myReduce = function(callback, initialValue) {let accumulator = initialValue;let startIndex = 0;// 若未提供初始值,使用数组第一个元素作为初始值if (initialValue === undefined) {accumulator = this[0];startIndex = 1;}for (let i = startIndex; i < this.length; i++) {accumulator = callback(accumulator, this[i], i, this);}return accumulator;
};
const arr = [1, 2, 3, 4];
console.log(arr.myReduce((acc, cur) => acc + cur, 0)); // 10

二、150道面试题目录列表

文章序号Javascript面试题150道
1Javascript面试题及答案150道(001-015)
2Javascript面试题及答案150道(016-030)
3Javascript面试题及答案150道(031-045)
4Javascript面试题及答案150道(046-060)
5Javascript面试题及答案150道(061-075)
6Javascript面试题及答案150道(076-090)
7Javascript面试题及答案150道(091-105)
8Javascript面试题及答案150道(106-120)
9Javascript面试题及答案150道(121-135)
10Javascript面试题及答案150道(136-150)
http://www.lryc.cn/news/610453.html

相关文章:

  • Linux 交换空间管理
  • 15个命令上手Linux!
  • 力扣top100--哈希
  • PandasAI连接LLM对MySQL数据库进行数据分析
  • 【笔记】重学单片机(51)(下)
  • ArcGIS的字段计算器生成随机数
  • 数据库提权
  • 并发编程常用工具类(下):CyclicBarrier 与 Phaser 的协同应用
  • (论文速读)RMT:Retentive+ViT的视觉新骨干
  • Hadoop HDFS 3.3.4 讲解~
  • 嵌入式知识篇---闪存
  • mysql 数据库系统坏了,物理拷贝出数据怎么读取
  • Deepoc 赋能送餐机器人:从机械执行到具身智能的革命性跨越
  • JavaScript 中的流程控制语句详解
  • 机器学习实战:逻辑回归深度解析与欺诈检测评估指标详解(二)
  • Redis缓存详解及常见问题解决方案
  • MySQL 基本操作入门指南
  • MCP进阶:工业协议与AI智能体的融合革命
  • 使用 SecureCRT 连接华为 eNSP 模拟器的方法
  • typeof和instanceof区别
  • Linux学习记录(八)文件共享
  • 认识pytorch与pytorch lightning
  • BackgroundTasks 如何巧妙驾驭多任务并发?
  • 我的创作纪念日____在 CSDN一年来的成长历程和收获
  • openvela之内存管理
  • Linux 磁盘管理与分区配置
  • VUE+SPRINGBOOT从0-1打造前后端-前后台系统-注册实现
  • 向量魔法:Embedding如何赋能大模型理解世界
  • Go语言select
  • Git基础玩法简单描述