前端面试JS

前端常见面试题二十一

2019-08-01  本文已影响203人  jw_fc89

目录:
1、手写promise封装axios
2、如何解决回调地狱
3、请详解移动端点透发生场景、原因及解决方案(最优)
4、详述前端性能优化的手段
5、浏览器输入网址回车发生了什么
6、页面的渲染过程
7、列举你知道的浏览器内核
8、如何优化SPA首屏加载慢的问题

1、手写promise封装axios

import Axios from "axios";
class Http {
  //request 方法
  request(params) {
    return new Promise((resolve, reject) => {
      Axios({
        method: params.type || "get",
        url: params.url,
        data: params.data,
        headers: params.headers
      })
        .then(res => {
          if (res.data.code === 0) {
            resolve(res);
          } else {
            alert(res.data.msg);
          }
        })
        .catch(err => {
          reject(err.statusText); //失败
        });
    });
  }
}
export default Http;

使用:
ps:注册短信验证码的请求

//引入封装好的axios
import Http from "../utils/http";
//实例化一个类
const _http = new Http();

//注册的请求
class RegisterRequest {
  //短信验证码
  CodeVerifier(mobile) {
    return _http.request({
      url: `https://api.it120.cc/small4/verification/sms/get?mobile=${mobile}`
    });
  }
}
//抛出
export default RegisterRequest;

页面中引用

//引入
import Product from "../services/product";
//实例化
const _product = new Product();
export default {
created(){
     _product.CodeVerifier().then(res => {
     //res 就是响应回来的数据
       res.data.data;
    });
  }
}
目录结构

2、如何解决回调地狱

1. 拆解 function:将各步拆解为单个的 function
function buildCatList(list, returnVal, fn) {
    setTimeout(function (name) {
        var catList = list === '' ? name : list + ',' + name
        fn(catList)
    }, 200, returnVal)
}

buildCatList('', 'Panther', getJanguar)

function getJanguar(list) {
    buildCatList(list, 'Janguar', getLynx)
}

function getLynx(list) {
     buildCatList(list, 'Lion', print)
}

function print(list) {
    console.log(list)
}

定时器中的回调函数处在外层函数中的作用域内,并通过参数传入,没有产生全局变量,没有重复代码。但是 function 拆分的方式其实仅仅只是拆分代码块,时常会不利于后续维护

2. 通过 Promise 链式调用的方式
function buildCatList(list, returnVal) {
    return new Promise(function (resolve, reject) {
        setTimeout(function (name) {
            var catList = list === '' ? name : list + ',' + name
            resolve(catList)
        }, 200, returnVal)
    })
}

buildCatList('', 'Panther').then(function (res) {
    return buildCatList(res, 'Janguar')
}).then(function (res) {
    return buildCatList(res, 'Lion')
}).then(function (res) {
    console.log(res)
})

// Panther,Janguar,Lion

Promise 函数虽然改变了之前回调地狱的写法,但是在根本上还是函数套函数,看起来不是那么的美观
参考地址:https://blog.csdn.net/fu983531588/article/details/89476190

3、请详解移动端点透发生场景、原因及解决方案(最优)

点透场景:

层A覆盖在层B上面,常见的有对话框等,层A用touchstart或者tap(zepto)事件点击进行隐藏或者移开,由于click晚于touchstart,超过300ms,当层A隐藏后,click到的是下面的层B,此时层B的click事件会触发,或者其上的a链接会跳转,input,select会吊起键盘。

解决方案:

1、使用一个(透明)遮罩层,屏蔽所有事件,然后400ms(对于IOS来说是个理想值)后自动隐藏

.touchFix{visibility: hidden;width: 100%;height: 100%;position: absolute;left: 0px;top: 0px;z-index: 9999;}

2、 touchstart换成touchend,因为触发touchend需要200ms所以可以把触发时间这个原理问题解决掉

$("#cbFinish").on("touchend", function (e) {
  e.preventDefault();
});

3、下层避开click事件,如a链接改为span等标签,使用js跳转页面
4、 zepto最新版已经修复了这个问题,或者使用fastclick、hammer等通用库
zepto的tap事件原理zepto的tap事件是通过touchstart,touchend(android 4.0.x不支持touchend,通过touchmove 设置定时器触发touched)模拟出来的,事件是绑定在document上,大体思路是在touchstart的时候向对象附加点击的x,y;(其中还包含很多细节,比如设置最后点击时间,设置长按定时器等);touchmove的过程动态的计算手势在view上的偏移点,最后touchend 根据偏移点确定是否是点击,如果是点击动态的构建一个event然后根据
设置的状态获取是单机、双击。非zepto的tap事件未必会出现点透问题。

4、详述前端性能优化的手段

链接:https://www.nowcoder.com/questionTerminal/47e17ccb60d64fb9878a678cbdb81e96?toCommentId=398202
来源:牛客网

1.内容方面

减少http请求

代码压缩

js代码写在</body>之前

浏览器缓存(cookie/sessionStorage/localStorage)

将静态资源放置在子域名下,实现并行下载数目增加

缓存ajax结果

减少DOM节点数

2.服务器方面

cdn加速

gzip压缩

3.js

引用压缩过的库(.min)

减少操作DOM节点,必要时将节点缓存起来(离线更新);

少用递归或者用尾递归优化

减少全局变量

懒加载

预加载

4.css

精简css代码的编写,减少嵌套层次

使用sprite图

尽量采用简写

用link代替@import

动画要用在脱离文档流的元素上

5.图片处理

图片一般要压缩到小于200k(banner等)

可将资源放至子域名下

用iconfont代替小图标

5、浏览器输入网址回车发生了什么?

1、建立TCP连接
2、Web浏览器向Web服务器发送请求命令
3、Web浏览器发送请求头信息
4、Web服务器应答
5、Web服务器发送应答头信息
6、Web服务器向浏览器发送数据:
7、Web服务器关闭TCP连接 :

6、页面的渲染过程

1.解析html文件,创建DOM树

自上而下解析,遇到任何样式(link、style)和脚本(script)都会阻塞
  1)css加载不会阻塞html文件的解析,但会阻塞dom的渲染
  2)css加载会阻塞后面js语句的执行
  3)js会阻塞html的解析和渲染
  4)没有defer和async标签的script会立即加载并执行
  5)有async标签的js,js的加载执行和html的解析和渲染并行
  6)有defer标签的js,js的加载和html的解析和渲染并行,但会在html解析完成后执行,在触
发DOMContentLoaded事件前执行
  7)DOMContentLoaded和onload的区别:DOMContentLoaded在html解析完毕后执行,loload在页面完全加载完成后执行(包括样式和图片)

2.解析css,生成CSSOM,css对象模型
3.dom和css合并,构建渲染树(Render Tree)
4.布局(Layout)和绘制(Paint),重绘(repaint)和重排(reflow/回流)

1)重绘:根据元素的新属性重新绘制,使元素呈现新的外观
  2)重排:当渲染树中的一部分因为元素的规模尺寸,布局,隐藏等改变而需要重新构建
  3)重排必定会引发重绘,但重绘不一定会引发重排

监听资源加载完成有四种方式
  1. window.onload = function(){....}
  2. window.addEventListener("load",function(){....});
  3. document.body.onload = function(){....}
  4. <body onload = "load()">

7、列举你知道的浏览器内核

1、Trident内核代表产品Internet Explorer,又称其为IE内核。Trident(又称为MSHTML),是微软开发的一种排版引擎。使用Trident渲染引擎的浏览器包括:IE、傲游、世界之窗浏览器、Avant、腾讯TT、Netscape 8、NetCaptor、Sleipnir、GOSURF、GreenBrowser和KKman等。

2、Gecko内核代表作品Mozilla FirefoxGecko是一套开放源代码的、以C++编写的网页排版引擎。Gecko是最流行的排版引擎之一,仅次于Trident。使用它的最著名浏览器有Firefox、Netscape6至9。

3、WebKit内核代表作品Safari、Chromewebkit 是一个开源项目,包含了来自KDE项目和苹果公司的一些组件,主要用于Mac OS系统,它的特点在于源码结构清晰、渲染速度极快。缺点是对网页代码的兼容性不高,导致一些编写不标准的网页无法正常显示。主要代表作品有Safari和Google的浏览器Chrome。

4、Presto内核代表作品OperaPresto是由Opera Software开发的浏览器排版引擎,供Opera 7.0及以上使用。它取代了旧版Opera 4至6版本使用的Elektra排版引擎,包括加入动态功能,例如网页或其部分可随着DOM及Script语法的事件而重新排版。

上述所言只列举四大代表浏览器内核

8、如何优化SPA首屏加载慢的问题

1、模块化开发
2、利用懒加载技术
3、抽取css文件
4、采用预渲染
5、gzip代码压缩

上一篇下一篇

猜你喜欢

热点阅读