一些前端面试思考

回流和重绘

        先牢记这句话,回流必将引起重绘,而重绘不一定会引起回流。回流的代价要远大于重绘。

当你给一个元素更换颜色,这样的行为是不会影响页面布局的,DOM树不会变化,但颜色变了,渲染树得重新渲染页面,这就是重绘。

比如我们增删DOM节点,修改一个元素的宽高,页面布局发生变化,DOM树结构发生变化,那么肯定要重新构建DOM树,而DOM树与渲染树是紧密相连的,DOM树构建完,渲染树也会随之对页面进行再次渲染,这个过程就叫回流。

         换句话说,你可以简单粗暴地理解为重绘只是改变了样式树。而回流改变了DOM树(引起DOM树结构变化,页面布局变化)。

浏览器拿到HTML文本后如何解析

        html文件在没有写入html标签之前和txt文本是一个性质的,不含任何样式。只是单纯的文本预览文件。一旦加入了html标签,表示内容有了语义。浏览器的渲染引擎才会根据标签的语义开始解析。

解析一个文档意味着把它翻译成有意义的结构以供代码使用。解析的结果通常是一个表征文档的由节点组成的树,称为解析树或句法树。

解析器通常把工作分给两个组件——分词程序和解析程序。分词程序负责把输入切分成合法符号序列,解析程序负责按照句法规则分析文档结构和构建句法树。
【精选】你了解浏览器原理吗?说说浏览器解析html的过程_浏览器解析html过程_码上十七的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65335111/article/details/127400627

CSS树和DOM树怎么结合

【精选】Dom树 CSS树 渲染树(render树) 规则、原理_web18296061989的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/web18296061989/article/details/123421151

网页是如何渲染出来的,dom树和css树是如何合并的,浏览器的运行机制是什么,什么是否会造成渲染阻塞?_css 样式怎么合并到dom节点的-CSDN博客渲染树构建、布局及绘制浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分的,一是渲染引擎,另一个是JS引擎。渲染引擎在不同的浏览器中也不是都相同的。目前市面上常见的浏览器内核可以分为这四种:Trident(IE)、Gecko(火狐)、Blink(Chrome、Opera)、Webkit(Safari)。这里面大家最耳熟能详的可能就是 Webkit 内核了,Webkit 内核是当下浏览器世..._css 样式怎么合并到dom节点的https://blog.csdn.net/qq_22930381/article/details/101448112?utm_source=miniapp_weixin

eventLoop事件循环

var x = setTimeout(() => {console.log(1)},0)
var y = new Promise(function(resolve) {
    console.log(2);
    resolve();
    console.log(3)
})
y.then(() => {
    console.log(4)
})
console.log(5)

        依次输出2 3 5 4 1

        setTimeout产出宏任务,promise.then产出的是微任务。

        JavaScript是单线程的,意味着任务只能一次执行一个任务。
        宏任务(Macro Task)是指在当前任务队列中被调度的任务。例如:

  • DOM事件处理
  • setTimeout
  • setInterval
  • setImmediate(nodejs独有)
  • requestAnimationFrame(浏览器独有)
  • I/O操作(nodejs独有)

        微任务(Micro Task)是指在当前任务执行结束后需要立即执行的任务。例如:

  • Promise.then
  • Promise.catch
  • Promise.finally
  • MutationObserver

        Event Loop 翻译为事件循环,是JavaScript的一种执行机制。

        Event Loop的执行过程如下:

  1. 执行全局Script同步代码,这些同步代码可能会产生宏任务或者微任务。
  2. 执行所有微任务,直到微任务队列为空。
  3. 取出一个宏任务执行,执行过程中产生的微任务会加入微任务队列。
  4. 重复步骤2-3,直到所有任务都执行完毕。

原型链的概念

        就是实例对象和原型对象之间的链接,每一个对象都有原型,原型本身又是对象,原型又有原型,以此类推形成一个链式结构.称为原型链

什么是原型对象

        在声明了一个函数之后,浏览器会自动按照一定的规则创建一个对象,这个对象就叫做原型对象

怎么判断NULL

val === null

或: 

if(!val && typeof(val) != "undefined" && val!= 0) {

     
}

     

怎么中断请求

        jquery

var ajaxGet = $.get('xxx',{id:1},function(data){...});
ajaxGet.abort()

        axios

        使用 CancelToken.souce 工厂方法创建一个 cancel token

const CancelToken = axios.CancelToken;

        将token作为传参

const source = CancelToken.source();
axios.get('https://mdn.github.io/dom-examples/abort-api/sintel.mp4', {
  cancelToken: source.token
}).catch(function (thrown) {
  // 判断请求是否已中止
  if (axios.isCancel(thrown)) {
    // 参数 thrown 是自定义的信息
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

        这里用axios来判断中止状态

        主动取消:

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');

        方法二:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});

// 取消请求
cancel('Operation canceled by the user.');

        Fetch

        fetch是ES6新出的,基于promise设计,没有进行封装,属于原生js,所以在vue中使用的时候也不需要进行import引入就可以直接使用。

        fetch请求返回的是promise对象,需要进行json转换,所以需要两次.then()


fetch("/api/test/")
 .then(res => {
    return res.json();
 })
 .then(res => {
   // 这里返回的数据就是我们想要请求的json数据
   console.log(res);

        上面是get下面是post


const requestBody = {
  title: 'foo',
  body: 'bar',
  userId: 1
};
 
fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  body: JSON.stringify(requestBody),
  headers: {
    'Content-Type': 'application/json'
  }
})
.then(res => res.json())
.then(data => console.log(data))

        如果要终止 fetch 请求,则可以使用 Web 提供的 AbortController 接口。

   首先我们使用 AbortController() 构造函数创建一个控制器,然后使用 AbortController.signal 属性获取其关联 AbortSignal 对象的引用。当一个 fetch request 初始化时,我们把 AbortSignal 作为一个选项传递到请求对象 (如下:{signal}) 。这将信号和控制器与获取请求相关联,然后允许我们通过调用 AbortController.abort() 中止请求。

const controller = new AbortController();
let signal = controller.signal;
console.log('signal 的初始状态: ', signal);

const downloadBtn = document.querySelector('.download');
const abortBtn = document.querySelector('.abort');

downloadBtn.addEventListener('click', fetchVideo);

abortBtn.addEventListener('click', function() {
 controller.abort();
 console.log('signal 的中止状态: ', signal);
});

function fetchGetVideo() {
  //...
  fetch(url, {signal}).then(function(response) {
    //...
  }).catch(function(e) {
    reports.textContent = 'Download error: ' + e.message;
  })
}

function fetchPostVideo() {
  //...
  fetch(url,{
    name: "张三.avi",
    id: 18x
  },{
    signal: controller.signal // 传入signal
  }).then(function(response) {
    //...
  }).catch(function(e) {
    reports.textContent = 'Download error: ' + e.message;
  })
}

手写题

实现一个handler,handler(arr)返回一个对象 o
 要求:
1.调用o.next ().value 输出 
2.继续调用o.next().value 输出 2
3.继续调用o.next().value 输出 3

function o(arr) {
    this.data = arr;
    this.index = 0;
}
o.prototype.next = function() {
    this.index++;
    return this.data[this.index-1]
}
function handler(arr) {
    if (!Array.isArray(arr)) {return false}
    return new o(arr)
}
var c = handler([1,2,3])
c.next()
c.next()
c.next()

你可能感兴趣的:(javascript,前端)