[JS]精选面试题-3

1.说说前端中的事件流

HTML 与 JS 的交互是通过事件驱动来实现的,事件流描述的是JS从页面中接收事件的顺序

事件流包括事件捕获阶段->处于目标阶段->事件冒泡阶段

addEventListener事件柄最后的参数,如果是true,程序就在捕获阶段执行 , 如果是false,程序就在冒泡阶段执行

IE浏览器只支持事件冒泡。

2.事件委托

把事件设置在父元素身上,通过事件冒泡,实现父元素监听子元素的事件

  1. 减少事件处理的数量:你只需在父元素上绑定一个事件处理程序,就可以管理该父元素下所有子元素的事件。
  2. 增加程序的灵活性:当新的子元素被添加到父元素中时,它们会自动继承来自父元素的事件处理程序,无需再次手动绑定事件。

事件模型

一、定义

事件模型是一种设计模式。它允许对象之间通过事件进行通信和处理

二、组成部分

  1. 事件源(Event Source):它是事件的起始点,负责生成并触发事件。
  2. 事件对象(Event Object):包含事件信息的对象,事件发生时会被传递给事件监听器。
  3. 事件监听器(Event Listener):负责监听事件,在事件发生时执行处理函数。

三、类型

在Web开发中,DOM事件模型是处理用户交互的主要机制。它分为DOM0级事件、DOM2级事件和IE事件。

  • DOM0级事件通过为元素添加事件处理属性(如onclick)来实现;
  • DOM2级事件则通过addEventListener()方法来实现,支持为元素添加多个事件监听器并控制事件处理的时机(捕获或冒泡阶段);
  • IE事件模型通过attachEvent()方法实现,但仅支持IE浏览器。

3.JS⾃定义事件

在JavaScript中,自定义事件允许创建并触发自己的事件,然后监听这些事件来执行特定的代码。

1. 创建自定义事件

你可以使用CustomEvent构造函数来创建一个自定义事件。CustomEvent构造函数接受几个参数,包括事件名称(type)、一个配置对象(可选,用于设置事件是否可冒泡、是否可取消等)。

const myEvent = new CustomEvent('myCustomEvent', {  
    bubbles: true, // 是否冒泡  
    cancelable: true, // 是否可以取消  
    detail: { // 传递给事件处理程序的额外数据  
        message: 'Hello, this is a custom event!'  
    }  
});

2. 监听自定义事件

使用addEventListener方法可以为元素或对象添加事件监听器,以监听自定义事件。

document.addEventListener('myCustomEvent', function(e) {  
    console.log(e.detail.message); // 输出: Hello, this is a custom event!  
});  

3. 触发自定义事件

使用dispatchEvent方法在元素或对象上触发自定义事件。

// 在document上触发  
document.dispatchEvent(myEvent);  
  
// 或者在特定元素上触发  
myElement.dispatchEvent(myEvent);

注意事项

  • 自定义事件名称不应与现有的DOM事件名称冲突。
  • 使用bubblescancelable选项可以控制事件的冒泡和取消行为。
  • detail属性是传递给事件处理函数的额外数据,它应该是一个对象,这样可以传递更复杂的数据。
  • 在移除事件监听器时,请确保使用与添加时相同的函数引用(除非使用removeEventListener的捕获阶段变体)。

4.addEventListener()和attachEvent()的区别

addEventListener()和attachEvent()都是JavaScript中用于绑定事件处理程序的方法,但它们之间存在几个关键的区别。以下是这些区别的详细分析:

1. 兼容性

  • addEventListener():是W3C标准的事件监听方法,在现代浏览器中得到广泛的支持
  • attachEvent():主要用于旧版本的IE浏览器(如IE7和IE8)

2. 方法名和参数

  • addEventListener():接受三个参数。第一个参数是事件类型(不含"on"前缀,如"click"),第二个参数是事件处理函数,第三个参数用于指定事件在捕获阶段或者冒泡阶段执行
  • attachEvent():接受两个参数。第一个参数是事件类型(含"on"前缀,如"onclick"),第二个参数是当事件发生时调用的函数。在IE浏览器中,默认不支持事件冒泡

3. this的指向

  • addEventListener():在事件处理函数中,this关键字指向触发事件的元素。
  • attachEvent():在事件处理函数中,this关键字指向window对象。因为在attachEvent方法中,事件处理程序是在全局作用域下执行的。

4. 事件的执行顺序

  • addEventListener():绑定的事件处理程序会按照它们被添加的顺序执行。
  • attachEvent():绑定的事件处理程序会按照它们被添加的相反顺序执行,这是IE浏览器特有的行为。

5. 移除事件监听器

  • addEventListener():使用removeEventListener()方法来移除之前添加的事件监听器。
  • attachEvent():使用detachEvent()方法来移除之前添加的事件监听器。

5.mouseover 和 mouseenter 的区别

mouseover:当鼠标移入元素或其子元素都会触发事件,有冒泡的过程。对应的移除事件是 mouseout

mouseenter:当鼠标移入元素本身会触发事件,不会冒泡,对应的移除事件是 mouseleave

6.什么是事件监听

事件监听的作用是监听事件的触发, 是事件模型的组成部分

事件模型有三部分

  1. 事件源(Event Source):触发事件的对象。
  2. 事件对象(Event):记录事件的相关信息
  3. 事件监听器(Event Listener):监听事件的触发,并触发处理函数

7.谈谈你对ES6的理解

ES6也称为ECMAScript 2015,是JavaScript语言的一个重大更新版本

ES6的主要新特性

  1. 变量声明
    • let:具有块级作用域,不允许在同一作用域内重复声明同一个变量。
    • const:也具有块级作用域,声明时必须进行初始化赋值,且赋值后不能再重新赋值修改其值(但如果是一个对象或数组,可以修改其内部属性或元素)。
  1. 箭头函数
    • 提供了更简洁的函数写法,并且不创建自己的this上下文,继承外层函数的this值,避免了this指向错误的问题。
  1. 模板字符串
    • 使用反引号(``)标识,支持多行字符串和动态内容插入,使字符串的拼接和处理更加方便、灵活和易读。
  1. 解构赋值
    • 允许从数组或对象中提取值,并将其赋给变量,提高了代码的可读性和便捷性。
  1. 扩展运算符
    • 主要用于展开数组或对象,以及函数参数传递等场景,提供了更灵活的操作方式。
  1. 剩余参数
    • 允许将不定数量的参数表示为一个数组,便于处理函数中的可变参数。
  1. 模块化
    • ES6引入了模块化系统,允许开发者将大型代码库分解为更小、更独立的模块,提高了代码的可维护性和复用性。
  1. 新数据结构
    • 引入了MapSet等新的数据结构,提供了更高效的遍历和查找功能。
  1. 异步编程
    • 支持Promiseasync/await等异步编程特性,提高了异步编程的效率和可读性。

ES6的应用与影响

  • 前端开发:ES6的新特性极大地提升了前端开发的效率和体验,使得开发者能够编写更加简洁、易读和高效的代码。
  • 生态系统:ES6的发布促进了JavaScript生态系统的快速发展,涌现出大量基于ES6特性的工具和库,如Babel等转译器、Webpack等模块打包器等。

8.箭头函数的特性

1. 简洁的语法

  • 使用=>表示函数定义:箭头函数使用=>符号来定义,这使得代码更加简洁。

2. 不绑定自己的this

  • 继承外层函数的this:箭头函数不创建自己的this值,它会捕获其所在上下文的this值。
  • 无法改变this指向:由于箭头函数的this是词法上确定的,因此call()apply()bind()方法无法更改箭头函数内部this的指向。

3. 不拥有arguments对象

  • 箭头函数没有自己的arguments对象。如果需要访问所有参数,使用剩余参数(...args)。

4. 不具有prototype属性

  • 不是构造函数:箭头函数没有prototype属性,因为它们不是构造函数。因此,不能使用new关键字来调用箭头函数。

7. 注意事项

  • 返回对象字面量:如果箭头函数需要返回一个对象字面量,则必须将该对象字面量包裹在括号中,否则会被解释为函数体的一部分。
  • 多重箭头函数:多重箭头函数(即箭头函数内部再嵌套箭头函数)可以形成高阶函数,但需要注意作用域和this的绑定。

示例

// 简洁的语法  
const add = (a, b) => a + b;  
  
// 不绑定自己的this  
const person = {  
  name: 'Alice',  
  greet: () => console.log(this.name), // 注意:这里的this指向全局对象,而不是person对象  
  greetWithArrow: function() {  
    return () => console.log(this.name); // 这里的this指向person对象  
  }  
};  
  
person.greet(); // 可能输出undefined,取决于全局环境  
person.greetWithArrow()(); // 输出Alice  
  
// 不拥有arguments对象  
const sum = (...args) => args.reduce((a, b) => a + b, 0);  
console.log(sum(1, 2, 3)); // 输出6  
  
// 不具有prototype属性  
const func = () => {};  
console.log(func.prototype); // undefined  
  
// 返回对象字面量  
const getPerson = () => ({ name: 'Bob' });  
console.log(getPerson()); // 输出{ name: 'Bob' }

9.对原⽣Javascript了解程度

  1. 基础语法
    • 变量声明(var, let, const)及其作用域(块级作用域与函数作用域)。
    • 数据类型(原始类型如string, number, boolean, null, undefined, symbol(ES6新增),以及复杂类型如Object, Array, Function)。
    • 运算符(算术运算符、比较运算符、逻辑运算符、位运算符等)。
    • 条件语句(if...else, switch)和循环语句(for, while, do...while)。
  1. 函数与闭包
    • 函数声明与函数表达式。
    • 高阶函数、回调函数和匿名函数。
    • 闭包的概念及其用途(如封装私有变量)。
    • this关键字的作用及其在不同场景下的绑定规则(默认绑定、隐式绑定、显式绑定、new绑定)。
  1. 对象与原型链
    • 对象的字面量语法和构造函数创建对象。
    • 原型(__proto__)和原型链的概念,以及如何通过原型实现继承。
    • Object.prototype上的方法(如hasOwnProperty, toString, valueOf等)。
    • ES6中引入的class关键字和类继承。
  1. 数组与集合
    • 数组的常用方法(如push, pop, shift, unshift, slice, splice, map, filter, reduce等)。
    • 数组迭代方法(forEach, for...of循环)。
    • 集合类型(如Set, Map及其迭代器)。
  1. 异步编程
    • 回调函数的使用及其缺点(如回调地狱)。
    • Promise对象及其链式调用。
    • async/await语法糖,使得异步代码看起来更像是同步代码。
  1. DOM与BOM操作
    • DOM(文档对象模型)的基本操作(如获取元素、修改元素内容、添加/删除事件监听器等)。
    • BOM(浏览器对象模型)的基本操作(如操作窗口、定时器、导航和定位等)。
    • 了解并应用AJAX(Asynchronous JavaScript and XML)进行异步数据交换。
  1. ES6+新特性
    • 模板字符串、默认参数、展开语法(...)、箭头函数等语法糖。
    • 模块系统(ES6 Modules)。
    • Symbol类型、SetMap集合、ProxyReflectAPI等。
    • Promiseasync/await等异步解决方案。
    • class语法和类的继承。
  1. 性能优化与安全
    • 了解JavaScript执行机制(如事件循环、任务队列、宏任务与微任务)。
    • 掌握性能优化的技巧(如减少DOM操作、使用事件委托、优化图片和资源加载等)。
    • 了解并避免常见的安全漏洞(如XSS攻击、CSRF攻击)。

10.attribute和property的区别是什么

  • attribute 是 dom 元素在HTML中 作为标签拥有的属性;
  • property 是 dom 元素在JS中 作为对象拥有的属性。
  • 在默认情况下,Attribute和Property的值是同步的。
  • 但是,一旦用户通过界面交互(如输入文本)改变了元素的状态,Property的值会更新,而Attribute的值则不会(除非通过代码显式更新)。

11.eval是做什么的

  • 用法:eval函数接受一个字符串作为参数。如果字符串是表达式,eval会计算并返回表达式的值;如果字符串表示的是语句,eval会执行这些语句。
  • 示例eval("2 + 3")会返回5
  • 安全性:eval可以执行任意代码,应避免在生产环境中使用eval来执行不可信的代码。

12.window.onload和$(document).ready

window.onload: 页面所有元素加载完成后执行

window.onload = function() {  
  // 页面加载完成后执行的代码  
};  
 
// 或者使用 addEventListener(可以添加多个监听器)  
window.addEventListener('load', function() {  
  // 页面加载完成后执行的代码  
});

$(document).ready: DOM渲染完成后执行

$(document).ready(function() {  
  // DOM加载完成后执行的代码  
});  
 
// 或者使用更简洁的写法  
$(function() {  
  // DOM加载完成后执行的代码  
});
  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值