基础相关
1 前端需要注意哪些seo
- 合理的
title
、description
、keywords
:搜索对着三项的权重逐个减小,title
值强调重点即可,重要关键词出现不要超过2次,而且要靠前,不同页面title
要有所不同;description
把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面description
有所不同;keywords
列举出重要关键词即可 - 语义化的
HTML
代码,符合W3C规范:语义化代码让搜索引擎容易理解网页 - 重要内容
HTML
代码放在最前:搜索引擎抓取HTML
顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容一定会被抓取 - 重要内容不要用
js
输出:爬虫不会执行js获取内容 - 少用
iframe
:搜索引擎不会抓取iframe
中的内容 - 非装饰性图片必须加
alt
- 提高网站速度:网站速度是搜索引擎排序的一个重要指标
2 从浏览器输入栏输入url到显示的过程
- 浏览器根据请求的
URL
交给DNS
域名解析,找到真实IP
,向服务器发起请求; - 服务器交给后台处理完成后返回数据,浏览器接收文件(
HTML、JS、CSS
、图象等); - 浏览器对加载到的资源(
HTML、JS、CSS
等)进行语法解析,建立相应的内部数据结构(如HTML
的DOM
); - 载入解析到的资源文件,渲染页面,完成。
3 dom的重绘和回流
- 重绘是当节点需要更改外观而不会影响布局的,比如改变
color
就叫称为重绘 - 回流是布局或者几何属性需要改变就称为回流。
- 回流必定会发生重绘,重绘不一定会引发回流。回流所需的成本比重绘高的多,改变父节点里的子节点很可能会导致父节点的一系列回流。
4 cookies,sessionStorage 和 localStorage 的区别
cookie
是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)- cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递
sessionStorage
和localStorage
不会自动把数据发给服务器,仅在本地保存- 存储大小:
cookie
数据大小不能超过4ksessionStorage
和localStorage
虽然也有存储大小的限制,但比cookie
大得多,可以达到5M或更大
- 有期时间:
localStorage
存储持久数据,浏览器关闭后数据不丢失除非主动删除数据sessionStorage
数据在当前浏览器窗口关闭后自动删除cookie
设置的cookie
过期时间之前一直有效,即使窗口或浏览器关闭
5 iframe有那些缺点?
iframe
会阻塞主页面的Onload
事件- 搜索引擎的检索程序无法解读这种页面,不利于
SEO
iframe
和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载- 使用
iframe
之前需要考虑这两个缺点。如果需要使用iframe
,最好是通过javascript
动态给iframe
添加src
属性值,这样可以绕开以上两个问题
6 网页性能优化有哪些?如何提高网页的性能(此题很重要,大家注意,面试前要背诵常用的方法)
content
方面- 减少
HTTP
请求:合并文件、CSS
精灵、inline Image
- 减少
DNS
查询:DNS
缓存、将资源分布到恰当数量的主机名 - 减少
DOM
元素数量
- 减少
Server
方面- 使用
CDN
- 配置
ETag
- 对组件使用
Gzip
压缩
- 使用
Cookie
方面- 减小
cookie
大小
- 减小
css
方面- 将样式表放到页面顶部
- 不使用
CSS
表达式 - 使用
<link>
不使用@import
Javascript
方面- 将脚本放到页面底部
- 将
javascript
和css
从外部引入 - 压缩
javascript
和css
- 删除不需要的脚本
- 减少
DOM
访问
- 图片方面
- 优化图片:根据实际颜色需要选择色深、压缩
- 优化
css
精灵 - 不要在
HTML
中拉伸图片
7 link 和 @import的区别
link
功能较多,可以定义RSS
,定义Rel
等作用,而@import
只能用于加载css
- 当解析到
link
时,页面会同步加载所引的css
,而@import
所引用的css
会等到页面加载完才被加载 @import
需要IE5
以上才能使用link
可以使用js
动态引入,@import
不行link
是HTML
方式,@import
是CSS方式link
最大限度支持并行下载,@import
过多嵌套导致串行下载,出现FOUC
(文档样式短暂失效)link
可以通过rel="alternate stylesheet"
指定候选样式- 浏览器对
link
支持早于@import
,可以使用@import
对老浏览器隐藏样式 @import
必须在样式规则之前,可以在css文件中引用其他文件- 总体来说:
link
优于@import
8 对BFC规范的理解?
- 它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用
9 谈谈对于闭包的理解?使用场景(不要简单回答函数嵌套函数)
闭包的定义其实很简单:函数 A
内部有一个函数 B
,函数 B
可以访问到函数 A
中的变量,那么函数 B
就是闭包
function A() {
let a = 1
window.B = function () {
console.log(a)
}
}
A()
B() // 1
闭包存在的意义就是让我们可以间接访问函数内部的变量
经典面试题,循环中使用闭包解决 var
定义函数的问题
for (var i = 1; i <= 5; i++) {
setTimeout(function timer() {
console.log(i)
}, i * 1000)
}
首先因为 setTimeout
是个异步函数,所以会先把循环全部执行完毕,这时候 i
就是 6
了,所以会输出一堆 6
解决办法有三种
- 第一种是使用闭包的方式
for (var i = 1; i <= 5; i++) {
;(function(j) {
setTimeout(function timer() {
console.log(j)
}, j * 1000)
})(i)
}
在上述代码中,我们首先使用了立即执行函数将 i
传入函数内部,这个时候值就被固定在了参数 j
上面不会改变,当下次执行 timer
这个闭包的时候,就可以使用外部函数的变量 j
,从而达到目的
2.第二种就是使用 setTimeout
的第三个参数,这个参数会被当成 timer
函数的参数传入
for (var i = 1; i <= 5; i++) {
setTimeout(
function timer(j) {
console.log(j)
},
i * 1000,
i
)
}
3.第三种就是使用 let
定义 i
了来解决问题了,这个也是最为推荐的方式
for (let i = 1; i <= 5; i++) {
setTimeout(function timer() {
console.log(i)
}, i * 1000)
}
10 谈谈你对 js 作用域链的理解(变量作用域)
- 作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到
window
对象即被终止,作用域链向下访问变量是不被允许的 - 简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期
11 js原型、原型链
- 每个对象都会在其内部初始化一个属性,就是
prototype
(原型),当我们访问一个对象的属性时 - 如果这个对象内部不存在这个属性,那么他就会去
prototype
里找这个属性,这个prototype
又会有自己的prototype
,于是就这样一直找下去,也就是我们平时所说的原型链的概念 - 关系:
instance.constructor.prototype = instance.__proto__
- 特点:
JavaScript
对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变
- 当我们需要一个属性的时,
Javascript
引擎会先看当前对象中是否有这个属性, 如果没有的 - 就会查找他的
Prototype
对象是否有这个属性,如此递推下去,一直检索到Object
内建对象
12 谈谈你对于this的理解(此题不要忘了箭头函数,以及this指向出现问题的解决方案 预保留this)
this表示当前对象,this的指向是根据调用的上下文来决定的,默认指向window对象。
一、全局环境:
全局环境就是在里面,这里的this始终指向的是window对象。
二、局部环境:
1)在全局作用域下直接调用函数,this指向window。
2)对象函数调用,哪个对象调用就指向哪个对象。
3)使用 new 实例化对象,在构造函数中的this指向实例化对象。
4)使用call或apply改变this的指向。
5)箭头函数没有this指向,this取决于他所在的上下文(环境)。
6) 在嵌套函数中的this指向也是一个问题,可以使用预保留this更正this的指向,就是提前使用变量接收this,然后下面不使用this,使用那个变量;
13 new一个函数 做了什么
1,和普通函数执行一样,会形成一个私有的作用域(栈内存)
2,形参赋值,变量提升
3,浏览器会创建一个空对象出来,并将this指向这个对象
4,代码自上而下执行,遇到this.xxx=xxx,就存储到之前创建好的空对象中
5,默认不用return,也会返回这个对象
14 js运行机制(js如何运行)(js运行之前先找var声明的变量以及function声明函数块),这题考的是变量声明提前,以及function函数块提前
15 ajax工作原理
1.Ajax简介
Ajax(Asyncchronous JavaScript and Xml),翻译过来就是说:异步的javaScript和xml, Ajax不是新的编程语言,而是一种使用现有标准的新方法。
Ajax的优点:在不重新加载整个页面的情况下,可以与服务器交换数据,并更新部分网页的艺术。
2. Ajax的工作原理
Ajax的工作原理相当于在用户和服务器之间加了一个中间层(Ajax引擎),使用户操作与服务器响应异步化。并不是所有用户请求都提交服务器。像一些数据验证和数据处理等都交给Ajax引擎自己来做,只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。
3. Ajax实现步骤
1. 创建XMLHttpRequest 2. 设置请求方式 3. 调用回调函数 4. 发送请求
16 js模块化 amd cmd
一、CommonJS
在使用Node开发程序的时候,这个程序由很多个模块组成,每一个模块都是一个文件(一个单独的作用域)。Node模块采用的就是CommonJS规范,该规范的核心思想是允许模块通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或 module.exports 来导出需要暴露的接口
CommonJS模块的特点如下。
1、所有代码都运行在模块作用域,不会污染全局作用域。
2、模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
3、NMP中已经有将近20万个可以使用模块包
缺点:
1、同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载
2、浏览器资源是异步加载的不能非阻塞的并行加载多个模块
CommonJs所加载的模块一般都已经存在本地的硬盘里面,当我们执行某个文件的时候会一同加载文件里面require所引入的文件,加载起来非常快,不要考虑异步加载的方式。但是这个只是在于服务器端,如果是浏览器端,要从服务器加载模块就必须采用异步的方式,于是 乎就有了AMD CMD的解决方案;
1.amd
Asynchronous Module Definition(异步模块定义)。它是一个在浏览器端模块化开发的规范。它不是javascript原生支持,所以使用AMD规范进行页面开发需要用到对应的库,也就是RequireJS,AMD其实是RequireJS在推广的过程中对模块定义的范围化的产出。
它的实现方案是:先定义所有依赖,然后在加载完成后的回调函数中执行。
AMD是预加载, 只有一个接口:define(id?,dependencies?,factory); 它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,注意的是这些依赖文件并没有书写顺序的区别;
优点:
适合在浏览器环境中异步加载模块
可以并行加载多个模块
缺点:
提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不顺畅
不符合通用的模块化思维方式,是一种妥协的实现
2.cmd
CMD是另一种js模块化方案,它与AMD很类似,不同点在于:AMD 推崇依赖前置、提前执行,CMD推崇依赖就近、延迟执行。
Common Module Definition(CMD),是seajs推崇的规范,CMD则是依赖就近,用的时候再require。CMD 推崇 as lazy as possible(尽可能的懒加载,也称为延迟加载,即在需要的时候才加载)
AMD依赖前置,在定义模块时就声明其所要依赖的模块
优点:
1、依赖就近,延迟执行
2、可以很容易在 Node.js 中运行
缺点:依赖 SPM 打包,模块的加载逻辑偏重
CMD是按需加载依赖,在用到那个模块再去require
AMD在使用前就准备好,CMD是用到了再去准备模块
17 什么是同源限制(跨域相关)
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。
当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。
如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
1.什么是同源
域名、协议、端口相同,也就是在同一个域里。
2.非同源受到的限制
cookie不能读取 (如我在这一个站点无法读另一个站点的cookie)
dom无法获得
ajax请求不能发送
3.什么是浏览器跨域
例如:
一个域的页面去请求另一个域的资源;
A域的页面去请求B域的资源。
18 如何解决跨域问题(cors 反向代理 jsonp等)
1.cors
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
优点是:正统,符合标准,
缺点是:需要服务器端配合,比较麻烦。
2.jsonp
AJAX 无法跨域是受到“同源政策”的限制,但是带有src属性的标签(例如
3 反向代理方式
反向代理和正向代理的区别:
正向代理(Forward Proxy),通常都被简称为代理,就是在用户无法正常访问外部资源,比方说受到GFW的影响无法访问twitter的时候,我们可以通过代理的方式,让用户绕过防火墙,从而连接到目标网络或者服务。
反向代理(Reverse Proxy)是指以代理服务器来接受 Internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 Internet 请求连接的客户端,此时,代理服务器对外就表现为一个服务器。
如何使用反向代理服务器来达到跨域问题解决:
前端ajax请求的是本地反向代理服务器
本地反向代理服务器接收到后:
修改请求的 http-header 信息,例如 referer,host,端口等
修改后将请求发送到实际的服务器
实际的服务器会以为是同源(参考同源策略)的请求而作出处理
19 同步和异步的区别
同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。
同步,就是实时处理(如打电话),比如服务器一接收客户端请求,马上响应,这样客户端可以在最短的时间内得到结果,但是如果多个客户端,或者一个客户端发出的请求很频繁,服务器无法同步处理,就会造成涌塞。
同步如打电话,通信双方不能断(我们是同时进行,同步),你一句我一句,这样的好处是,对方想表达的信息我马上能收到,但是,我在打着电话,我无法做别的事情。
异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。
异步,就是分时处理(如收发短信),服务器接收到客户端请求后并不是立即处理,而是等待服务器比较空闲的时候加以处理,可以避免涌塞。
20 如何解决js异步回调地狱(promise、async、await、generator等)
1.什么是回调地狱
在异步编程中,许多操作都会放在回调函数(callback)中,每增加一个异步请求,就会多添加一层回调函数的嵌套,多个异步操作就形成了强耦合,只要有一个操作需要修改,它的上层回调函数和下层回调函数,可能都要跟着修改,过多的回调也就会导致陷入“回调地狱”。
2.promise
Promise 对象存在以下三种状态:
Pending(进行中)
Fulfilled(已成功)
Rejected(已失败)
promise,它不是新的语法功能,而是一种新的写法,允许将回调函数的嵌套,改成链式调用。
Promise对象是一个构造函数,接受一个带了resolve和reject参数的函数;
在状态由pending变为fulfilled时,从resolve中将value传出;
在状态由pending变为rejected时,将error抛出
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数
Promise 提供then方法加载回调函数,catch方法捕捉执行过程中抛出的错误。
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
3.Generator 函数
1.function关键字与函数名之间有一个星号;2.函数体内部使用yield表达式,定义不同的内部状态
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
2.调用遍历器对象的next方法,使得指针移向下一个状态
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
3.for...of循环可以自动遍历 Generator 函数时生成的Iterator对象,且此时不再需要调用next方法。
function* foo() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
return 6;
}
for (let v of foo()) {
console.log(v);
}
4.async/await
async 函数其实就是 Generator 函数的语法糖
await后一般是一个Promise对象。
async函数返回一个 Promise对象时,就可以使用then方法添加回调函数。
当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
const asyncReadFile = async function () {
const f1 = await readFile('/etc/fstab');
const f2 = await readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
21 es6新增了哪些属性(常用的整理回答)
因为字数太多详细见这篇文章
https://blog.csdn.net/weixin_43307658/article/details/86698281
22 简述http协议
因为字数太多详细见这篇文章
https://blog.csdn.net/qq_28602957/article/details/52852140?utm_source=distribute.pc_relevant.none-task
23 移动端 布局方案有哪些实现方式
一、固定布局
固定布局是第一次做移动端时最好的选择方式,思路沿用PC端,上手比较快。在标签里把 viewport 加好,然后设想整个网页的宽度为 320px 即可。 其他地方根据 PC 端来布局。 缺点:大屏手机显示网页比较宽,固定布局宽度参照永远是 320px,导致左右两 边会有空白。
二、流动布局
流动布局与固定宽度布局基本不同点就在于对网站尺寸的测量单位不同,流动布局就是使用百分比来代替px作为单位。 优点是流动布局可以很好解决自适应需求。缺点是不够灵活,添加元素时,需要更改其他元素的值。
三、bootstrap布局
bootstrap是一个比较流行的响应式前端框架,利用bootstrap的栅格系统可以实现响应式的移动端布局。栅格系统:Bootstrap中定义了一套响应式的网格系统,其使用方式就是将一个容器划分成12列,然后通过col-xx-xx的类名控制每一列的占比, 在使用的时候,我们给相应的div设置col-lg-2 col-md-3 col-sm-4 col-xs-6,以此完成布局。
四、媒体查询+REM布局
使用媒体查询可以根据不同的设备宽度加载不同的css样式。rem是一个相对单位,会根据根节点的字体大小来计算的,使用媒体查询和rem可以实现移动端的响应式。
五、flex布局
Flexbox是CSS3引入的新的布局模式,也称为弹性布局,他会根据页面的剩余宽度自动分配空间。 它决定了元素如何在页面上排列,使它们能在不同的屏幕尺寸和设备下可预测地展现出来。它能够扩展和收缩 flex 容器内的元素, 以最大限度地填充可用空间。Flexbox布局最适合应用程序的组件和小规模的布局,而网格布局更适合那些更大规模的布局。
24 请简述rem布局原理
1、em
em作为font-size的单位时,其代表父元素的字体大小,em作为其他属性单位时,代表自身字体大小——MDN
比如父元素font-size:12px;
自身元素如果写成:font-sise:2em;则自身元素用px表示就是24px(相对父元素字体大小);
但是自身元素设置:width:2rem,那么自身元素用px表示就是48px(相对自身字体大小);
2.2、rem
rem作用于非根元素时,相对于根元素字体大小;rem作用于根元素字体大小时,相对于其出初始字体大小——MDN
比如根元素(html)设置font-size=12px; 非根元素设置width:2rem;则换成px表示就是24px;
如果根元素设置成font-size=1rem;则根元素换成px就是相对于初始字体大小,一般是12px;
2.3、vm/vh
vw : 视口宽度的 1/100;vh :视口高度的 1/100 —— MDN
在pc端,视口宽高就是浏览器得宽高;
25 flex弹性布局有哪些属性
flex容器属性详解:
flex-direction:row/column;(横排/竖排) 决定元素的排列方向;
flex-wrap:nowrap/wrap/wrap-reverse(翻转);排列不下时如何排,默认排不下就压缩进行排
flex-flow是: flex-direction 和 flex-wrap的简写;(例如:flex-flow:row nowrap;)
justify-content:center; 元素在主轴上的对齐方式(center元素居中对齐);
align-items 元素在交叉轴的对齐方式;
flex元素属性详解:
flex-grow 当有多余空间时,元素的放大比例;
flex-shirink当空间不足时,元素的缩小比例;
flex-basis 元素在主轴上占据的空间;
flex时grow / shrink / basis的简写;
order 定义元素的排列顺序;
align-self 定义元素自身的对齐方式;
26 call apply 和bind的区别
call 和 apply 的共同点
它们的共同点是,都能够改变函数执行时的上下文,将一个对象的方法交给另一个对象来执行,并且是立即执行的。
为何要改变执行上下文?举一个生活中的小例子:平时没时间做饭的我,周末想炖个腌笃鲜尝尝。但是没有适合的锅,而我又不想出去买。所以就问邻居借了一个锅来用,这样既达到了目的,又节省了开支,一举两得。
改变执行上下文也是一样的,A 对象有一个方法,而 B 对象因为某种原因,也需要用到同样的方法,那么这时候我们是单独为 B 对象扩展一个方法呢,还是借用一下 A 对象的方法呢?当然是借用 A 对象的啦,既完成了需求,又减少了内存的占用。
另外,它们的写法也很类似,调用 call 和 apply 的对象,必须是一个函数 Function。接下来,就会说到具体的写法,那也是它们区别的主要体现。
call 和 apply 的区别
它们的区别,主要体现在参数的写法上
call 的写法
Function.call(obj,[param1[,param2[,…[,paramN]]]])
需要注意以下几点:
调用 call 的对象,必须是个函数 Function。
call 的第一个参数,是一个对象。 Function 的调用者,将会指向这个对象。如果不传,则默认为全局对象 window。第二个参数开始,可以接收任意个参数。每个参数会映射到相应位置的 Function 的参数上。但是如果将所有的参数作为数组传入,它们会作为一个整体映射到 Function 对应的第一个参数上,之后参数都为空。
apply 的写法
Function.apply(obj[,argArray])
需要注意的是:
它的调用者必须是函数 Function,并且只接收两个参数,第一个参数的规则与 call 一致。
第二个参数,必须是数组或者类数组,它们会被转换成类数组,传入 Function 中,并且会被映射到 Function 对应的参数上。这也是 call 和 apply 之间,很重要的一个区别。
bind 的使用
最后来说说 bind。在 MDN 上的解释是:bind() 方法创建一个新的函数,在调用时设置 this 关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。
它的语法如下:
Function.bind(thisArg[, arg1[, arg2[, …]]])
bind 方法 与 apply 和 call 比较类似,也能改变函数体内的 this 指向。不同的是,bind 方法的返回值是函数,并且需要稍后调用,才会执行。而 apply 和 call 则是立即调用。
如果 bind 的第一个参数是 null 或者 undefined,this 就指向全局对象 window。
总结
call 和 apply 的主要作用,是改变对象的执行上下文,并且是立即执行的。它们在参数上的写法略有区别。
bind 也能改变对象的执行上下文,它与 call 和 apply 不同的是,返回值是一个函数,并且需要稍后再调用一下,才会执行。
27 函数的防抖和节流
一、防抖函数
1.1 概念:
触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
1.2 使用场景:
就像是我的搜索栏功能,是在里面内容变化后就实时触发搜索事件,但是有时候我们输
的内容很长,在没有输完的时候就触发了事件,这样对性能来说是不好的,造成了很多
无用的请求,这时候就需要用到防抖函数,来让其在搜索内容变化后的200毫秒内如果
没有再更改才发起请求。
1.3 实现防抖函数的思路:
在高频触发事件的时候,取消原来的延时事件。
二、节流函数
2.1 概念:
高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率;
2.2 使用场景:
就像我接了一个任务,只能在5秒完成任务给回复,在执行后的这5秒内,你再怎么给
我布置任务我都不管直接当没听到,直到到5秒后执行完这个任务,你才可以再次给
我布置任务,以此类推。。。
2.3 实现思路:
每次触发事件时都判断当前是否有等待执行的延时函数,如果有直接截断事件不用往下执行了;
三、个人理解两者的区别
防抖函数和节流函数的一个区别就是防抖是按照最后一次触发为下一次事件执行的时间计算点,
前面的没满足间隔时间的都从最后这一次开始来决定什么时候执行延时事件;
而节流函数是按照第一次触发事件作为时间计算点,后面没到间隔时间的事件都忽略;
28 移动端1px问题如何解决?
原因
由于不同的手机有不同的像素密度导致的。如果移动显示屏的分辨率始终是普通屏幕的2倍,1px的边框在devicePixelRatio=2的移动显示屏下会显示成2px,所以在高清瓶下看着1px总是感觉变胖了
解决方法
1.在ios8+中当devicePixelRatio=2的时候使用0.5px
2.伪类 + transform 实现
原理是把原先元素的 border 去掉,然后利用 :before 或者 :after 重做 border ,并 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。
优点:所有场景都能满足,支持圆角(伪类和本体类都需要加border-radius)
缺点:对于已经使用伪类的元素(例如clearfix),可能需要多层嵌套
3.viewport + rem 实现
这种兼容方案相对比较完美,适合新的项目,老的项目修改成本过大。
在devicePixelRatio = 2 时,输出viewport:
在devicePixelRatio = 3 时,输出viewport:
优点:所有场景都能满足,一套代码,可以兼容基本所有布局
缺点:老项目修改代价过大,只适用于新项目
4.使用box-shadow模拟边框
利用css 对阴影处理的方式实现0.5px的效果
样式设置:
.box-shadow-1px {
box-shadow: inset 0px -1px 1px -1px #c8c7cc;
}
优点:代码量少,可以满足所有场景
缺点:边框有阴影,颜色变浅
29 对象 深拷贝和浅拷贝
浅拷贝 —-只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”,换句话说,浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变。
深拷贝 —-在计算机中开辟了一块新的内存地址用于存放复制的对象。
区别:浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;深拷贝是拷贝多层,每一级别的数据都会拷贝出来;
30 长链接 双向通信 websocket(什么时候用,怎么用)
详细见这篇文章
http://www.cocoachina.com/articles/896577?filter=mac
vue常见面试题
vue常见面试题点击
https://juejin.im/post/5d59f2a451882549be53b170
2 vue面试题中如果是后台管理 可能会问到vue中如何实现权限管理,大家去搜索。手摸手撸后台管理中有提到,还有,大家也注意看一下 vue-element-admin
3 vuex是什么,简述,同时,vuex如何实现长久存储
react常见面试题
http://note.youdao.com/noteshare?id=d4316ae35ab0e5f8c082218adf4d9047&sub=DE835BC97EEE49C1BA430377A2A366C9
小程序常见面试题
https://www.jianshu.com/p/c604914d325d
其他常问的问题?
1开发过程中遇到的最大的问题是什么?怎么解决的
2有没有用过第三方的插件或者库
(用过,如环信 做IM库) (IM是即时通信的意思,自己百度,如实时聊天,语音视频等)