前端常见面试(个人总结的一些知识点)

一、event loop 事件循环:

浏览器 eventloop
  • eventloop事件循环是一种执行模型一种运行机制,在不同的地方有不同的实现,主要分为浏览器的event loop和nodejs的event loop;在事件循环中有两个重要的概念,宏队列和微队列
  • 首先,对于浏览器的event loop来说,是html5定义的规范,但是是在浏览器实现的,在浏览器中:宏队列主要包括settimeout和setinterval,微队列主要有promise。主要执行过程是:
  • 浏览器首先会将同步任务执行完毕,这时调用栈会被清空
  • 之后会从微任务队列中取出位于队首的回调任务,遵从先进先出的原则依次放入调用栈中执行,直到栈空,如果此时回调函数中又生成了微任务,将其放在队尾等待调用
  • 当微任务队列为空的时候,这时将调用宏队列,将队首任务放入调用栈执行;(一次只能执行一个宏队列)如果宏任务中产生了微任务,就去先调用微任务,再去调用下一个宏任务
  • 然后重复步骤,这就是浏览器的eventloop
nodejs eventloop

nodejs的eventloop是基于libuv实现的,在事件循环执行宏队列时,nodejs的回调任务有6个阶段,timer(settimeout和setinterval)、I/O callback阶段、idle,prepare阶段、poll阶段、check阶段、close 阶段。这6个阶段构成了4个宏队列分别是:Timers Queue、IO Callback Queue、Check Queue、close callback Queue;

-nodejs 事件循环和浏览器事件循环最主要的区别就是:浏览器可以看做一个宏队列一个微队列;而nodejs是4个宏队列和2个队列,所以就会有队列的执行先后问题,在微队列中首先会执行NextTick Queue(process.nexttick) 在执行传统的微队列比如promise等,在执行宏队列任务时,需要将每一类宏队列的任务全部执行完毕,才执行对应产生的微队列。

二、浏览器缓存:强缓存和协商缓存

HTTP报文就是浏览器和服务器间通信时发送及响应的数据块。
浏览器向服务器请求数据,发送请求(request)报文;服务器向浏览器返回数据,返回响应(response)报文。
报文信息主要分为两部分
1.包含属性的首部(header)————————–附加信息(cookie,缓存信息等)与缓存相关的规则信息,均包含在header中
2.包含数据的主体部分(body)———————–HTTP请求真正想要传输的部分

强缓存

当我在没有缓存,第一次请求服务器的时候,服务器会将数据和缓存规则一并返回,缓存规则存放在响应头中, 主要是Expires/Cache-Control来表明缓存失效规则,因为在expires中缓存到期时间是服务器的时间,而客户端和服务器的时间可能存在差异,所以先在基本上都使用的cache-control,强缓存主要设置max-age属性,即到期时间,在这个期间客户端访问数据均走缓存

协商缓存

在第一次请求服务器时,服务器会返回资源,并且返回一个资源的缓存标识,一起存到浏览器的缓存数据库。

当第二次请求资源时,浏览器会首先将缓存标识发送给服务器,服务器拿到标识后判断标识是否匹配,

如果不匹配,表示资源有更新,服务器会将新数据和新的缓存标识一起返回到浏览器;

如果缓存标识匹配,表示资源没有更新,并且返回 304 状态码,浏览器就读取本地缓存服务器中的数据。
在学号是协商缓存中主要有:
last-Modified/If-Modified-Since :服务器返回的资源最后修改时间

etag/if-none-match:资源在服务器的唯一标识

三、节流和防抖

防抖:对于短时间内,连续出发的事件,防抖的含义是让某个时间限内,事件处理函数只执行最后一次或最开始的第一次。
//实现防抖函数
        function debounce(fn, timer) {
            let time = null;
            return function () {
                if (time) {
                    clearTimeout(time)
                }
                time = setTimeout(fn, timer)
            }
        }
节流:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。
 //实线节流函数
        function throttle(fn, timer) {
            let flag = true
            return function () {
                if (!flag) {
                    return false
                } //在一段时间内flag始终为false
                flag = false
                setTimeout(() => {
                    fn();
                    flag = true;
                }, timer)
            }
        }

三、web worker

Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。

Web Worker 有以下几个使用注意点。

(1)同源限制

分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。

(2)DOM 限制

Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。

(3)通信联系

Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。

(4)脚本限制

Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。

(5)文件限制

Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

四、原型链

prototype 在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象。
proto 这是每个对象(除null外)都会有的属性,叫做__proto__,这个属性会指向该对象的原型。
  • 当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止
  • 每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。

五、new一个构造函数的过程

  • 创建一个新对象,将它的引用赋值给this,继承函数的原型
  • 通过this将构造函数的属性添加给这个对象
  • 最后返回这个this指向的新对象,也就是实例
let newMethods = function (Parent, ...rest) {
    let child = Object.create(Parent.prototype);
    let ruselt = Parent.apply(child, rest)
    return typeof result === 'object' ? result : child;
}

const child = newMethods(ssss, "zdd");

六、promise原理

  • 首先promise解决的异步问题,同时他的应用场景主要是解决回到地狱的问题,promise 可以实现在多个请求发送完成后,再得到或者处理某个结果,
  • promise的原理:promise主要三个状态 pending、Fulfilled、rejected,当promise构造函数需要传入一个函数,函数中有两个参数分别是resolve和reject,在promise中有一个then,他的主要功能是当promise对象状态发生改变时执行相应操作,当然promise是基于发布订阅者模式实现的
function myPromise(constructor) {
    let self = this;
    self.status = "pending";
    self.value = undefined;
    self.reason = undefined;
    //定义观察数组
    self.onFullfilledArray = []
    self.onRejectedArray = []
    function resolve(value) {
        if (self.status == "pending") {
            self.value = value;
            self.status = "resolved"
            self.onFullfilledArray.forEach(fn => {
                fn(self.value)
            });
        }
    }
    function reject(reason) {
        if (self.status == "pending") {
            self.reason = reason;
            self.status = "rejected"
            self.onRejectedArray.forEach(fn => {
                fn(self.reason)
            })
        }
    }
    try {
        constructor(resolve, reject);
    } catch (e) {
        reject(e);
    }
}
myPromise.prototype.then = function (onFullfilled, onRejected) {
    let self = this;
    switch (self.status) {
        case "pending":
            self.onFullfilledArray.push(function () {
                onFullfilled(self.value)
            })

            self.onRejectedArray.push(function () {
                onRejected(self.reason)
            })
            break;
        case "resolved":
            onFullfilled(self.value);
            break;
        case "rejected":
            onRejected(self.reason);
            break;
        default:
    }
}
new myPromise((resolve, reject) => {
    console.log(123);
    // resolve(222)
    setTimeout(function () {
        resolve(222)
    }, 2000)
}).then(data => {
    console.log(data);
})

七、Content-type

服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。

application/x-www-form-urlencoded
  • 这应该是最常见的 POST 提交数据的方式了。浏览器的原生 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。
multipart/form-data
  • 这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 表单的enctype 等于 multipart/form-data。
application/json
  • 通过序列化json字符串的方式进行编码,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。
text/xml
  • 忽略xml头所指定bai编码du格式而默认采用zhius-ascii编码

八、mouseover和mouseleave的区别

  • mouseover:只要鼠标指针移入事件绑定的元素及其子元素,都会触发mouseover事件
  • mouseleave:只有鼠标指针移入事件绑定的元素时,才会触发mouseleave事件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值