前言
博主主页👉🏻蜡笔雏田学代码
专栏链接👉🏻【前端面试专栏】
今天继续学习前端面试题相关的知识!
感兴趣的小伙伴一起来看看吧~🤞
什么是事件监听
addEventListener()方法,用于向指定元素添加事件句柄,它可以更简单的控制事件。语
法为:
javascript">element.addEventListener(event, function, useCapture);
- 第一个参数是
事件的类型
(如 “click” 或 “mousedown”)。 - 第二个参数是
事件触发后调用的函数
。 - 第三个参数是
布尔值
,用于描述事件是冒泡还是捕获。(该参数是可选的。)
事件传递有两种方式:冒泡和捕获。
事件传递定义了元素事件触发的顺序,如果你将 P 元素插入到 div 元素中,用户点击 P元素,在冒泡中,内部元素先被触发,然后再触发外部元素,在捕获中,外部元素先被触发,再触发内部元素。
事件委托以及冒泡原理
事件委托
是利用冒泡阶段的运行机制
来实现的,就是把一个元素响应事件的函数委托到另一个元素,一般是把一组元素的事件委托到他的父元素上,委托的优点是减少内存消耗,节约效率,动态绑定事件。事件冒泡
就是元素自身的事件被触发后,如果父元素有相同的事件,如 onClick 事件,那么元素本身的触发状态就会传递,也就是冒到父元素,父元素的相同事件也会一级一级根据嵌套关系向外触发,直到 document/window,冒泡过程结束。
介绍一下 promise,及其底层如何实现
Promise 是一个对象,保存着未来将要结束的事件,有两个特征:
对象的状态不受外部影响
,Promise 对象代表一个异步操作,有三种状态,pending:进行中,fulfilled:已成功,rejected:已失败,只有异步操作的结果,才可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也就是 promise 名字的由来。一旦状态改变,就不会再变
,promise 对象状态改变只有两种可能:从 pending 到fulfilled 或者从 pending 到 rejected,只要这两种情况发生,状态就凝固了,不会再改变,这个时候就称为定型 resolved。
Promise 的基本用法
let promise1 = new Promise(function(resolve,reject){
setTimeout(function(){
resolve('ok')
},1000)
})
promise1.then(function su***ess(val){
console.log(val)
})
深浅拷贝的区别
浅拷贝
只是复制指向某个对象的指针,而不是复制对象的本身,新旧对象还是共享同一块内存,修改新对象会改变原对象。(拷贝指向对象的指针)
如果是数组,我们可以利用数组的一些方法,比如 slice,concat 方法返回一个新数组的特性来实现拷贝,但假如数组嵌套了对象或者数组的话,使用 concat 方法克隆并不完整,如果数组元素是基本类型
,就会拷贝一份,互不影响,而如果是对象或数组
,就会只拷贝对象和数组的引用
,这样我们无论在新旧数组进行了修改,两者都会发生变化,我们把这种复制引用的拷贝方法称为浅拷贝
深拷贝
会创造另外一个一模一样的对象,即使嵌套了对象,两者也互相分离(把这个对象原封不动地再copy出新的一份,和原对象互不相干),新对象和原对象不共享同一块内存,修改新对象不会修改原对象。(拷贝对象)
如何深拷贝一个数组
这里介绍一个技巧,不仅适用于数组还适用于对象!
var arr = ['old', 1, true, ['old1', 'old2'], { old: 1 }]
console.log(JSON.stringify(arr)) //["old",1,true,["old1","old2"],{"old":1}]
var new_arr = JSON.parse(JSON.stringify(arr));
console.log(new_arr); //['old', 1, true, ['old1', 'old2'], { old: 1 }]
原理是 JOSN 对象中的 stringify 可以把一个
js 对象
序列化为一个JSON 字符串
,parse 可以把JSON 字符串
反序列化为一个js 对象
,通过这两个方法,也可以实现对象的深复制。但是这个方法不能够拷贝函数。
let、const、var的区别
- var 声明的变量是
全局或者整个函数块
的,而 let,const 声明的变量是块级的变量
。 - var 声明的变量存在变量提升,let,const 不存在。
- let 声明的变量允许重新赋值,const 不允许。
ES6 箭头函数的特性
ES6 增加了箭头函数,基本语法为:
let func = value => value;
相当于
let func = function (value) {
return value;
};
箭头函数与普通函数的区别在于:
箭头函数没有 this
,所以需要通过查找作用域链
来确定 this 的值,这就意味着如果箭头函数被非箭头函数包含,this 绑定的就是最近一层非箭头函数的 this。- 箭头函数没有自己的 arguments 类数组 对象,但是可以访问外围函数的 arguments 对象。
- 不能通过 new 关键字调用,同样也没有 new.target 值和原型。
setTimeout 和 Promise 的执行顺序
首先我们来看这样一道题:
setTimeout(function () {
console.log(1)
}, 0);
new Promise(function (resolve, reject) {
console.log(2)
for (var i = 0; i < 10000; i++) {
if (i === 10) { console.log(10) }
i == 9999 && resolve();
}
console.log(3)
}).then(function () {
console.log(4)
})
console.log(5);
//打印结果:2 10 3 5 4 1
要先弄清楚 setTimeout(function,0)何时执行,Promise 何时执行,then 何时执行。
- setTimeout 这种异步操作的回调,只有主线程中没有执行任何同步代码的前提下,才会执行异步回调,而setTimeout(fun,0)表示立刻执行,也就是
用来改变任务的执行顺序
,要求浏览器尽可能快的进行回调
。- Promise 何时执行:Promise 新建后
立即执行
,所以 Promise 构造函数里代码同步执行的。- then 方法指向的回调将在当前脚本
所有同步任务执行完成后执行
。
那么 then 为什么比 settimeout 执行的早呢?
因为 settimeout(fun,0)不是真的立即执行,经过测试得出结论:执行顺序为:同步执行的代码 => Promise.then => setTimeout
今天的分享就到这里啦✨ \textcolor{red}{今天的分享就到这里啦✨} 今天的分享就到这里啦✨
原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下
🤞 点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!