前端面试题

目录

Html相关

Css相关

JavaScript相关

ReactJs相关

VueJs相关

webpack相关

Koa相关

Nodejs相关

Web相关

网络协议相关

浏览器相关


目录

Html相关

Css相关

JavaScript相关

ReactJs相关

VueJs相关

webpack相关

Koa相关

Nodejs相关

Web相关

网络协议相关

浏览器相关


Html相关

  • 什么是文档流?

文档流(Normal Flow):也叫作普通流/正常流,相对于盒子模型来说的,就是html元素默认在页面中的排版布局,比如div块级元素是从上到下,span等行内元素从左到右排列。

脱离文档流:就是将元素从排版布局中脱离出来,脱离文档流的方式:position中的absolute和fixed,还有float属性。

文本流:相对于文字段落来说的,是指html中文本的排版显示

  • 什么是dom什么是bom?

DOM:Document Object Model是文档对象模型,DOM遵循W3c的标准,定义了如何访问html文档元素,并允许脚本动态对文档进行操作,根比如document.getElementById(),getElementByName()等

BOM:Browser Object Model是浏览器对象模型,暂时还没有相关的标准,但是现代的浏览器都已经实现了获取和设置浏览器的一系列的操作,BOM包含windows(窗口)、navigator(浏览器)、screen(浏览器屏幕)、history(访问历史)、location(地址)等

  • 什么是web worker和websocket

web worker:是html5的一个新特性,让web应用程序可以具备多线程的处理能力,可以运行在后台的javascript,而不会影响页面其他正常处理和显示,可以将复杂需要时间的处理用web worker来处理。它的应用场景是,可以把一些阻塞页面渲染的一些js计算放到web worker中去做。

1.通过 worker = new Worker( url ) 加载一个JS文件来创建一个worker,同时返回一个worker实例。
2.通过worker.postMessage( data ) 方法来向worker发送数据。
3.绑定worker.onmessage方法来接收worker发送过来的数据。 
4.可以使用 worker.terminate() 来终止一个worker的执行。

web worker能做:

1.可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信

2.可以在worker中通过importScripts(url)加载另外的脚本文件

3.可以使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval()

4.可以使用XMLHttpRequest来发送请求

5.可以访问navigator的部分属性

缺点:

1.不能跨域加载JS

2.worker内代码不能访问DOM

3.各个浏览器对Worker的实现不大一致,例如FF里允许worker中创建新的worker,而Chrome中就不行

4.不是每个浏览器都支持这个新特性

 websocket:websoket是html5的一种新的网络协议,也是基于tcp的协议,它是持久的,可以持续在客户端和服务器端保持双工链接,服务器的更新可以被及时推送给客户端,不需要客户端再设置定时查询。

  • img标签中title和alt有什么区别?

title是鼠标滑过图片弹出框提示的信息,alt是在图片未成功加载情况下显示的信息

Css相关

  • 什么是css盒子模型?

在网页中,一个元素的空间构成主要包括内容(content),边框(border),内边距(padding),外边距(margin)这些构成,这些就像实际中的盒子一样,所以叫做css的盒子模型。

  • 盒子模型box-sizing中content-box和border-box的区别?

比如div的width和height都是100px,padding是10px,如果用content-box是不包含padding和border的元素,实际的高和宽是120px;border-box是包含padding和border的,实际的高和宽是设置的100px

  • 什么是flexbox布局?

弹性盒子布局,设置元素的display=flex,会影响其子元素的排列方式,会使块级元素不再独占一行。使用布局之后,其子元素无论多少都会在一行显示。并且通过设置一些属性能达到垂直居中,水平居中,对齐和排序等等,可以自由操作布局,当前所有的浏览器都支持,并且手机上在安卓和ios上也支持

  • bfc是什么?

BFC(Block Formatting Context)是块格式化上下文,简单来说就是一个独立的渲染区域,在bfc内部的元素不会影响到外面的元素,因为他们隔离互不影响的。

示例场景:比如两个div,同时设置margin:100px;这时候上下两个div的距离不是200px,而是100px,两个的外边距会重叠,这时候就需要用bfc来解决,分别用一个有bfc的div包裹着,这个bfc的div可以设置成overflow:hidden;来触发bfc即可。

触发条件:

1.根元素 float属性不为none 

2.position为absolute或fixed。

3.display为inline-block, table-cell, table-caption, flex, inline-flex。

4.overflow为hidden。

  • css的选择器有哪些呢?

  • ID 选择器, 如 #id{}

  • 类选择器, 如 .class{}

  • 属性选择器, 如 a[href="segmentfault.com"]{}

  • 伪类选择器, 如 :hover{}

  • 伪元素选择器, 如 ::before{}

  • 标签选择器, 如 span{}

  • 通配选择器, 如 *{}

  • css的优先级?

!import  > 内联样式 > ID 选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 标签选择器 = 伪元素选择器 > 通配选择器

  • 什么叫优雅降级和渐进增强?

其实就是向上兼容和向下兼容浏览器,优雅降级就是向下兼容,渐进增强就是向上兼容

  • sass和less的区别?

1.定义变量的符号不同,less是用@,sass使用$
2.语法有些不同,sass支持if else条件判断,以及for循环,还支持function函数
3.编译环境不同,less是基于javascript,在客户端环境处理,sass是基于ruby的,在服务器环境端处理。

4.作用域不同,sass中的变量修改,会按照修改前后顺序赋值。 less是只要变量被修改了,全局再引用都是被修改过的了。

  • px,em,rem的区别?

px:实际就是像素,px是是相对于显示器分辨率的

em:是相对父元素计算字体大小,如果父元素没有设置大小,会以body的字体大小或者浏览器默认大小来计算。

rem:称为root em,也就是说是以根节点来计算,它是以<html>根的字体大小来计算,不会依赖父元素,整个页面的字体大小设置好后都不会乱了。想多个端兼容,最好是使用rem。一般方便rem和px换算的话,html中定义font-size:62.5%,这样1rem就相当于10px了。

  • 移动端怎么实现响应性布局?

1.在head标签中加一根meta标签,

<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">

2.使用媒体查询,即 @media 查询,媒体查询可以针对不同的屏幕尺寸设置不同的样式,通过控制screen的min-width和max-width。

3.使用rem来代替px,rem会根据html节点的字体大小来计算。而em呢是根据父元素节点大小,所以相对于还是rem更适合方便一些。

  • link和@import的区别

两者都是外部引用css样式的方式,其他区别如下:

1.link是HTML提供的标签,不仅可以加载CSS文件,还可以定义rel连接属性,比如stylesheet,index,help,start,next,prev,contents等等;

2.@import是CSS提供的语法规则,只有导入样式表的作用;
       3.link引用CSS时,在页面载入时可以同时加载;@import需要页面网页完全载入以后加载。
       4.link支持使用js动态操作dom去添加删除标签;而@import不支持。

  • css 中可以让文字在垂直和水平方向上重叠的两个属性是什么?

垂直方向:line-height 
       水平方向:letter-spacing

  • css中怎么解决inline-block的空白间隙?

1.设置父元素的font-size为0,然后设置子元素的font-size。

2.父元素设置letter-spacing为负值,子元素设置letter-spacing:0px;即可。

3.子元素用margin-left来调整。

4.子元素用float:left;来布局。

  • css中垂直居中的方法

1.设置固定的高度,然后line-height等于这个高度。

2.设置父元素position:relative;子元素设置为position:absolute;top:50%;transform:translateY(-50%);意思通过设置translateY为-50%,就是自身的偏移量往上一半。

3.父元素设置postion:relative;子元素设置positon:absolute;top:0;bottom:0;margin:auto;若想水平也居中,再设置个left:0;right:0;即可

4.使用flex布局,父元素设置display:flex;align-items:center;如果想水平居中,父元素设置justify-content: center;

5.父元素使用display:table;子元素使用display:table-cell;vertical-align:middle;

  • 用css隐藏元素的几种方法

1.display:none;

2.visibilit:hidden;

3.opacity:0;

4.position:absolute;top:-999px;left:-999px;

5.transform: translateX(-500%);

  • css英文首字母大写

比如:hello it's ok,使用text-transform:capitalize; 输出:Hello It's Ok

  •  CSS优化、提高性能的方法有哪些?

避免过度约束

避免后代选择符

避免链式选择符

使用紧凑的语法

避免不必要的命名空间

避免不必要的重复

最好使用表示语义的名字。一个好的类名应该是描述他是什么而不是像什么

避免!important,可以选择其他选择器

尽可能的精简规则,你可以合并不同类里的重复规则

  • transition与animation的区别

他们虽然都可以做出动画效果,但是transition主要做简单的过渡效果,而animation可以做复杂的动画效果,在语法和用法上有一些区别。

transition是过渡属性,强调过渡,他的实现需要触发一个事件(比如鼠标移动上去,焦点,点击等)才执行动画,过渡只有一组(两个:开始-结束)关键帧。

animation是动画属性,他的实现不需要触发事件,设定好时间之后可以自己执行,且可以循环一个动画(设置多个关键帧)。
 

JavaScript相关

  • js编译原理?以及什么是ast

js是一种动态解释型语言,包含有:编译器(负责语法分析以及代码生成),引擎(负责js程序的编译和执行过程),作用域(负责收集并维护所有生成的标识符(变量),并实施一套非常严格的规则,确定当前执行的代码对这些变量的访问权限。

编译的顺序:  

1.词法解析,将代码字符串分解为词法单元,比如定义一个变量,var num = 10; 会逐个拆分。

2.语法分析,将词法单元转换成一棵由元素逐级嵌套的程序语法结构的树,也叫作抽象语法树,也就是AST,

3.生成代码,js引擎将抽象语法树AST转换为一组机器可执行的指令,比如创建变量,分配内存等

  • js数据类型都有哪些?

     基本数据类型:字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。

引用数据类型:对象(Object)、数组(Array)、函数(Function)。

  • typeoff的返回值都有哪些呢?

        有:string,number,boolean,object,undefined,function,ES6新增了symbol

  • js变量命名规则?

1.常用骆驼命名法,首字母小写。

2.以字母,下划线,$符号开头,不能以中文,空格,特殊标点符号,数字开头。

3.变量命名尽量简洁和意思明了,不能过长。

4.不能使用js里面的关键字命名。

  • es6去重方法?

Array.from(new Set([1,1,2,3]))

[...new Set([1,1,2,3])]

  • typeof 和 instanceof 的区别?

1.typeof可以判断一个变量是否为空,可以判断变量是属于哪个数据类型,比如返回number,string这些。注意的是对于 Array,Null 等特殊对象使用 typeof 一律返回 object,typeof undefined是返回undefined。

2.instanceof是判断一个变量是否属于某个对象的实例,比如:[] instanceof Array,输出true

  • 什么是闭包?

闭包是指一个能够读取其他函数内部变量的函数。

优点:1.变量在内存中,可以提高性能。2.避免全局变量的污染。3.可以保护私有成员变量。

缺点:1.因为变量可以一直在内存中,会内存消耗大,也可能会导致不会被垃圾回收,所以在使用完之后把变量赋值为null。

  • js中作用域有哪些?

1.全局作用域:声明在函数外部的变量,在代码中任何地方都能访问的到(没有用var声明的变量属于全局变量哦)

2.函数作用域:函数内声明的所有变量在函数体内始终是可见的,可以在整个函数的范围内使用。

3.块级作用域:是es6有的一个概念,通过一对{}花括号定义的代码块,在这里定义的所有变量在代码块外面都是不可见的,这个就叫块级作用域。使用let和const定义的变量,只会在这一范围内起作用,也不会存在变量提升。

  • 什么是变量提升?

js引擎在编译代码的时候,所有使用var声明的变量,都会被提升到当前作用域的顶部。同样函数也是会存在提升的。

  • 什么是暂时性死区?

let和const是块级作用域,声明的变量不会存在变量提升,在未声明之前就使用变量就会报错,所以在代码块内,使用let和const声明变量,先声明后使用是不行的,这在语法上称为‘暂时性死区‘,简称TDZ。

  • Array对象的属性有哪些?

constructor:返回对创建此对象的数组函数的引用。

length:设置或返回数组中元素的数目。

prototype :使您有能力向对象添加属性和方法。

  • Array对象方法有哪些?

concat() 连接两个或更多的数组,并返回拼加后的新数组。

pop() 删除数组最后一个元素,并返回该删除的元素。  

shift() 删除数组第一个元素,并返回该删除的元素。

unshift() 向数组的开头添加一个或更多元素,并返回新的长度。

push() 向数组的末尾添加一个或更多元素,并返回新的长度。

reverse() 颠倒数组中元素的顺序。

slice() 通过下标截取数组

splice() 删除或者替换数组元素

fill()将一个搞定的值填充一个数组中从开始位置到起始位置的所有元素

keys() 返回一个可以迭代的对象

sort() 对数组的元素进行排序

from()将一个类似数组或可迭代对象转换成一个数组

some()遍历时候,只要有一项满足,就返回true

every()遍历时候,全部都满足,才返回true

forEach()遍历数组

map()对数组中的每个元素进行处理,得到一个新的数组

filter()返回满足条件的数组元素

includes()判断数组中是否包含某一个值,会返回true和false

indexOf()判断数组中包含某一个值 ,存在则返回下标,不存在就返回-1

join()将数组中内容按照某个字符串分割,并返回分割后的字符串。

isArray()判断传递的对象是否是一个数组类型

toString()把数组转化为字符串

  • 对象和类的区别?

类是对象的抽象,对象是类的实例,对象是实际存在的,有对应的行为和属性。

  • ["1","2","3"].map(parseInt)的结果是多少?

答:[1,NaN,NaN],

['1','2','3'].map(parseInt)即

parseInt('1',0);radix 为 0,parseInt() 会根据十进制来解析,所以结果为 1;

parseInt('2',1);radix 为 1,超出区间范围,所以结果为 NaN;

parseInt('3',2);radix 为 2,用2进制来解析,应以 0 和 1 开头,所以结果为 NaN。
 

  • 介绍一些es6的特性

1.块级作用域:let,const。

2.变量解构赋值:如let [a,b]=[1,2],输出是a=1, b=2

3.字符串的扩展:比如新增includes(),startsWith(),endsWith(),padStart(),padEnd(),matchAll(),字符串模版等。

4.函数的扩展:箭头语法,双冒号运算符(可以像bind一样将冒号前面的对象绑定到冒号右边,比如 foo:bar 相当于 bar.bind(foo))

5.数组和对象的扩展:新增了扩展运算符(...),用来合并数组和对象,不过这种是浅拷贝,数组的方法也新增了from(),fill(),includes()等方5.法,对象也新增了Object.is(),Object.assign()浅拷贝的哦,Object.keys(),Object.values()等。

6.新增了Symbol原始数据类型。

7.新增了Set和Map,WeakSet,WeakMap,Set里面的值是不会重复的,WeakSet只能存对象,WeakMap只能接受对象和null作为key。

8.新增了Promise对象,用来处理异步操作,可以通过then链式调用,来控制异步代码执行顺序。

9.新增了Generator和Async和await来处理异步,和Promise一样的作用,async返回的其实就是一个Promise对象。

10.新增了Class的语法,可以用extends来实现继承。

11.es6的import,export语法来实现模块化,和commonJS的module是一样作用的。

  • es6中set和map区别?

set是没有元素可以重复的,map是键值对可以允许重复

  • this指向问题?

普通函数:只要是普通函数,即使是在箭头函数里面的普通函数,也是指向的window。严格模式下使用 "use strict" 声明后,输出this是undefined。

实例化对象或者字面量对象:这种是该对象调用了,this就指向这个对象,如果对象里面有一个普通函数调用了,还是指向的window,如果是箭头函数调用了,就指向当前的这个对象。

箭头函数:根据所在的环境,在哪个环境就指向谁。

  • 什么是函数柯里化?

柯里化(Currying)是把接受多个参数的函数变换成嵌套着接受一个单一参数的函数,并返回一个函数接受剩下的参数。这中间可嵌套多层这样的接受部分参数的函数,直至返回最后结果。

例如:

function add(a){
    return function(b){
        return function(c){
            return a+b+c;
        }
    }
}
console.log(add(1)(2)(3));
输出结果:6
  • call和apply的区别?

 1.apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, argsArray); 即A对象调用B对象的方法。
        2.call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2); 即A对象调用B对象的方法。
        3.参数不同,call可以接受多个参数,apply职能接受的一个数组参数。
        4.call和apply可以重新修改this的指向。

  • 怎么让一个构造函数的实例 instanceof 它为false?

主要是直接修改对象的prototype就可以了,就不是同一个实例了,比如下面:

 function Cat(){
            this.name='cat'
        }
        var cat = new Cat();
        Cat.prototype ={
            say:function(){
               console.log('a cat')
           }
       }
       console.log(cat instanceof Cat) // 这里输出false
  • 什么是构造函数?

构造函数也是普通的函数,只不过会通过new来调用并创建一个新的实例,这个函数就叫做构造函数。

  • 构造函数的执行流程?

     1.立刻在堆内存中创建一个新的空对象

      2.让this指向这个对象

      3.执行构造函数里的代码,给这个新的空对象添加属性和方法

      4.返回这个新的对象

  • 什么是原型和原型链?

原型:所有的函数都有一个prototype属性,这个就叫原型,也称为显示原型。我们用构造函数创建的对象会有prototype原型上面所有绑定的方法。

原型链:当我们用obj.xxx访问一个对象的属性时,会先在对象自身属性中查找,如果没有找到,再沿着__proto__这条链向上层去找,这样一层一层的查找就会形成一个链式的结构,就叫做原型链。如果找到原型链的顶层Object.prototype还没有,就返回null,也就是 Object.prototype.__proto__ === null。

  • prototype 和  __proto__  的区别?

①prototype(原型)是构造函数才有的属性,可以叫做显示原型,它实例化的对象包含prototype上所有共享的方法。(当构造函数new实例化一个对象时候,它实例化对象的__proto__指向了它构造函数的prototype);

②__proto__ 是对象(不论是普通对象还是构造函数实例化的对象)才有的属性,可以叫做隐式原型,用于指向创建它的构造函数的原型对象。(对象的__proto__会指向它构造函数的prototype);

function foo(){}
var f = new foo();
// 该实例化的对象的__proto__指向了其的构造函数prototype
console.log(f.__proto__ === foo.prototype) // 输出:true

var obj = {}
// __proto__指向构造函数的prototype
console.log(obj.__proto__ === obj.constructor.prototype) // 输出:true
  • 怎么用js给元素添加class?
// 为 <div> 元素添加 class:
document.getElementById("myDIV").classList.add("mystyle");
// 为 <div> 元素添加多个类:
document.getElementById("myDIV").classList.add("mystyle", "anotherClass", "thirdClass");
// 为 <div> 元素移除一个类:
document.getElementById("myDIV").classList.remove("mystyle");
// 为 <div> 元素移除多个类:
document.getElementById("myDIV").classList.remove("mystyle", "anotherClass", "thirdClass");

// 为 <div> 设置属性
document.getElementById("myDIV").setAttribute("title","this is a title");
  • js哪些情况会造成内存泄漏?

1.大量声明使用全局变量。2.闭包引起的内存泄漏。3.dom清空或者删除时候,绑定的事件未清除。4.定时器未被清除。5.子元素存在引用。

  • js中垃圾回收的策略?

标记清除:

  当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:"离开环境",这种标记离开环境的就回收内存。

引用计数:

机制就是跟踪一个值的引用次数,当声明一个变量并将一个引用类型赋值给该变量时该值引用次数加1,当这个变量指向其他一个时候,该值的引用次数便减一,当该值引用次数为0时就会被回收。

  • js中undefined和null区别?

这两个的值是不相等的,即undefined === null 是 false。undefined表示变量定义了未赋值,null表示变量的引用是空的。

注意(null == undefined)为true,是成立的,因为在ecmascript规范中,null和undefined的行为很相似,都表示一个无效的值,所以它们是相等的。

  • commonjs,amd,cmd的区别?

CommonJS, AMD, CMD都是JS模块化的规范。

1.CommonJs 是服务器端模块的规范,Node.js采用了这个规范。 根据CommonJS规范,一个单独的文件就是一个模块,加载模块使用require方法,CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。

var clock = require('clock');

clock.start();

2.AMD(Asynchronous Module Definition) 是 RequireJS (这里可以简记AR)定义的规范 ,AMD异步加载模块,AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块 。

require([module], callback);

3.CMD(Common Module Definition)是SeaJS (这里可以简记CS)定义的规范。CMD推崇就近依赖,只有在用到某个模块的时候再去require模块 。

require(['clock'],function(clock){

  clock.start();

});

  •  require和import的区别?

1.require是commonJS的规范

2.import是es6中的语法

3.require是运行时动态加载,import是编译的时候调用

4.require输出的是一个值的拷贝,import输出的值是引用

  • js中深拷贝和浅拷贝区别?

1.浅拷贝的对象和原对象的引用是同一个,当源对象发生改变,浅拷贝的对象也会改变。object.asign和...运算符属于浅拷贝

2.深拷贝是完全创建一个新的引用,可以用JSON.stringify和JSON.parse来实现,或者手动写函数,递归遍历对象,重新赋值个新的拷贝后的对象

  • 什么是事件流?

也就是事件处理的流程,是有先后执行顺序的,标准的事件流它分为3个阶段:事件捕获 》事件目标 》事件冒泡

  • 什么是事件模型?

就是事件的一个标准模型,分为3个模型。分别是:

1.原始事件模型(DOM0)

在原始事件模型中,事件发生后没有传播的概念,也没有事件流的产生,事件发生后就马上处理然后结束,比如:

document.getElementById("btn").onClick=function(){alert('hello')}

2.IE事件模型

这个是在ie系列浏览器里支持的,ie中的事件流不是标准的,它只有事件目标和事件冒泡,没有事件捕获,ie中创建事件是用attachEvent('onclick',function(){});移除用detachEvent('onclick',function(){}):   注意的是ie中组织事件冒泡的方法是获得event对象,这个event对象是用的全局变量window.event获得的,而且函数执行完毕,这个event就是null了。

3.DOM2事件模型

这个模型是W3C指定的标准模型,我们现在用的浏览器都是按照这个标准,在W3C指定的事件模型中,一次事件的发生包含3个过程:

* 事件捕获(事件被从document一直向下传播到目标元素,在这过程中依次检查经过的节 
          点是否注册了该事件的监听函数,若有则执行。)

* 事件处理阶段(事件到达目标元素,执行目标元素的事件处理函数)

* 事件冒泡阶段(事件从目标元素上升一直到达document,同样依次检查经过的节点是否注册 
了该事件的监听函数,有则执行。)

添加事件:document.getElementById('div').addEventListener('click',function(){},false)
addEventListener第三个参数是false就是事件冒泡,是true就是事件捕获。

删除:removeEveentListener('click')
  • 什么是事件委托?

说到事件委托,其实也是事件代理,都是表示有一个第三方去做某件事情。

委托就是通过事件冒泡机制,把事件监听函数绑定到父元素上,在父辈元素的监听函数中,可通过event.target属性拿到触发事件的原始元素,然后再对其进行相关处理。

举个例子,比如我们去饭店吃饭,小明说想吃蛋炒饭,小花说想吃牛肉面,小明和小花不可能直接告诉厨师吃什么,人多的话厨师记不清,这时候服务员出来了,服务员记录下来小明和小花想吃的饭,然后报给厨师,做好后,服务员根据做好的饭和订单上对应(event.target判断),依次给小明和小花, 这个服务员就是个委托,也是代理。

  • 同源策略是什么,还有跨域是什么?

同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以a.com是读取不了b.com下面的资源。

不受同源策略限制的有:
       1、页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
        2、跨域资源的引入是可以的,如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等。

跨域就是前面说的同源策略影响的解决办法,就是跨域。

跨域的方式有:

1.jquery ajax的jsonp跨域,通过设置回调。

2.通过docuemnt创建script,通过回调函数获取返回数据

2.通过修改document.domain来跨域。

3.cors实现跨域,主要是后端配置Access-control-allow-origin来实现。

4.nginx做代理也可以实现,配置proxy_pass地址。

5.在开发环境下也可以实现,比如可以在package.json中配置proxy。

具体也可以参考:https://segmentfault.com/a/1190000011145364

  • 什么是作用域?什么是作用域链?

作用域:作用域其实就是变量或者函数起作用的范围,比如定义一个var a在一个函数里,那这个a的作用域就是在这个函数里,外面是访问不到的。

作用域链:是javascript内部中一种变量、函数查找机制。进入执行环境后,访问一个变量时候js引擎会在当前作用域往上去找,直到找到global全局作用域为止,和原型链有一点相近,也是逐级往上去寻找,但是作用域链的顶层是window

  • 栈和堆的区别?

栈(stack)会自动分配内存空间,会自动释放,栈先进后出。堆(heap)动态分配的内存,大小不定,也不会自动释放,一般是手动释放,也可以由垃圾回收机制回收。

1.基本数据类型是直接值存到栈中的,占用一定的空间。

2.引用类型类型的数据实际存储是放到堆中,然后在栈中会存一个地址(指针),通过栈中的地址去堆中获取真正的值。

  • js异步加载的方法

1.在script标签中使用async属性,虽然可以实现,但是它是乱序执行的,只要加载完了就会执行,所以不能保证执行顺序。

2.在script标签里使用defer属性,对脚本进行延迟,直到页面元素加载完成为止,而且它是按照加载顺序执行脚本的

3.动态生成script标签,在onload里动态使用document生成标签。也可以用jquery的ready函数执行,

  • js中创建对象的方式有哪些?

1.直接通过字面量创建var obj = {};

2.直接通过new Object()方式创建。

3.工厂模式

4.构造函数模式

5.原型模式

6.组合模式(原型和构造函数)

  • js中实现继承的方式有哪些?

1.原型链继承。

2.es6的extends继承。

3.构造函数继承。

4.组合继承。

5.寄生式继承。

  • JS中的== 与 ===的区别

==:叫做相等运算符,比较时候会进行类型转换,值相等就是相等。

===:叫做严格运算符,只要类型不用,就不会相等。

  • sessionStorage 、localStorage 和 cookie 之间的区别?

共同点:都是保存在浏览器端、且同源的 
区别: 

1、创建方式不同:cookie是由服务器端创建,发送客户端,当用户发送请求后,会在http请求中携带传递到服务器端。而sessionStorage和localStorage是创建保存在客户端,也不会自动把数据发送给服务器。

2、存储大小不同:cookie数据不能超过4K,只适合保存很小的数据,比如会话标识。sessionStorage和localStorage本地存储可以达到5M以上。

3、数据有效期不同:sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭 。

4、作用域不同:sessionStorage只能在同一个浏览器页面中有效,或者打开链接和用window.open新打开一个页面也可以有效的,除了这些其他的情况都是不能共享的;localstorage和cookie都可以在所有同源窗口中都是共享的;

5、web Storage支持事件通知机制,可以将数据更新的通知发送给监听者,具体是在页面添加监听事件:window.addEventListener("storage", handleStorage, false);

6、web Storage的api接口使用更方便,比如setItem,getItem,removeItem,clear都可以很方便的操作。cookie必须自己手动封装。

  • 原生ajax的工作原理?
var xhr = new XMLHttpRequest(); // 创建xmlHttpRequest对象
xhr.onreadystatechange=function()  {
  if (xhr.readyState==4 && xhr.status==200)
     // 服务器正常响应后,获取返回数据
  }
xhr.open('get','http://222.11.11.2/getUser?id=1',false);//通过发送get或者post请求到服务器的url地址, 第三个参数是是否async,true是同步,false是异步
xhr.send(); // 发送
  • js中eventloop是什么?

event loop称为事件循环机制,javascript是单线程的,js中所有的任务都需要按顺序一个一个的执行,但是一个任务消耗太长,后面的任务就需要等待,为了解决这种情况,javascript把任务分为两种,一种是同步任务,一种是异步任务,同步任务会在主线程排队执行的任务;异步任务是会进入到任务队列task queue,任务队列还分为宏任务macro-task(setTimeout(),setInterval(),script块,Promise构造函数是宏任务)和微任务micro-task(Promise,process.nextTick(),Promise的then和catch是微任务)。当主线程中的任务执行完毕之后,会不断读取异步任务队列中的任务来执行,这就是事件循环。

执行异步任务队列中任务时候,如果有微任务了会先执行完所有的微任务,再执行下一个宏任务,没有微任务就会执行宏任务。

  • 什么是防抖和节流?

防抖:如果设定的时间到来之前,就连续触发事件,就重新开始延时执行事件。

// 函数防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){
 clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
 timer = setTimeout(function(){
 console.log("函数防抖");
 }, 300);
}; 

节流:当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

// 函数节流
var canRun = true;
document.getElementById("throttle").onscroll = function(){
 if(!canRun){
 // 判断是否已空闲,如果在执行中,则直接return
 return;
 }
 canRun = false;
 setTimeout(function(){
 console.log("函数节流");
 canRun = true;
 }, 300);
};
  • 什么是解构赋值?

解构赋值语法是一种js表达式,它使得将值从数组,属性,对象中提取到不同变量里。

比如:[a,b]=[10,20],结果是a=10,b=20;

  • js里求出数组中的最大值

1.使用for循环来比较

let num = 0;
for(let i = 0;i<array.length;i++){
	if(i>num){
		num=i;
	}
}

2.使用es6的语法

var n = Math.max(...array)
  • js实现数字千分位
第一种:直接用数字的原型方法
var num = 123456789;
num.toLocaleString();
第二种:使用正则
var num = 123456789;
var str = num.toString().replace(/(?=(?!(\b))(\d{3})+$)/g,",");

ReactJs相关

  • react是什么?

React 一个用于构建用户界面的 JAVASCRIPT 库。 React主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图),React是Facebook开发的一个项目,它是单向数据流的,和vue数据双向绑定不同。

  • react组件之间都是独立互不影响,state也是组件独立的,如果发生多次渲染,react的render函数自会渲染发生变化的地方,组件之间也是可以互相嵌套的。
  • react中使用函数组件和class创建组件的区别?

1.函数组件只能接收props。

2.使用es6 class创建的可以不单可以使用props,还可以使用this,和state,以及生命周期函数。

  • react中怎么绑定this?
1.在constructor里bind
constructor(props){
  super(props);
  this.handleClick=this.handleClick.bind(this);
}
2.使用属性初始化器语法
handleClick = () =>{}
3.在元素中的事件使用箭头函数
<div onClick={(e)=> this.handleClick(id,e)}>click me</div>
4.在元素的事件中也可以使用bind
<div onClick={this.handleClick.bind(this,id)}>click me</div>
  • react中的虚拟dom和diff算法理解

1.虚拟dom其实就是用一个对象来描述dom树,对数据和状态的变更会同步到虚拟dom上,通过计算新旧虚拟dom的差异,最终把变化的部分重新渲染。

2.diff算法是实现比较虚拟dom差异的一个算法,它可以对虚拟dom进行逐层的比较,如果树类型不同,就会重新创建,如果类型相同,属性不同,就会只更新属性不同的部分,如果在子节点后新增节点,会直接增加节点,如果在子节点前增加节点,会重新生成这几个节点。

3.给节点加key,key更方便diff算法计算出来节点之间的差异。

  • 什么是高阶组件?高阶组件就是一个没有副作用的纯函数,且该函数接受一个组件作为参数,并返回一个新的组件。
  • 什么是高阶函数?高阶函数是一个可以接受函数作为参数,并返回一个新的函数。
  • 什么叫纯函数?一个函数的返回结果只依赖于它的参数,并且不会对别的对象产生副作用,就叫做纯函数。
  • react中component和element的区别?

element:元素是构成react应用的最小单位,用来描述页面上看到的内容,可以用jsx语法创建一个元素,比如const element=<div>hello</div>,与浏览器dom元素不同的是,react中的元素实际上是普通的对象,所以没有办法调用dom原生的api。

component:组件就是一个方法或者一个类,可以接受任意的输入值(称之为props),并且返回一个需要在页面上展示的react元素。

  • 什么是redux框架?

Redux是一个流行的JavaScript框架,为应用程序提供一个可预测的状态容器。

那什么是可以预测化,我的理解就是根据一个固定的输入,必然会得到一个固定的结果。

核心概念,三大原则:①单一数据源 ②state是只读的 ③使用纯函数执行修改

处理流程,主要是action,reducer,store,

组件dispatch一个action,然后到reducer,reducer是一个纯函数,它接收到这个action,根据action的类型,来更新状态。

缺点:

1.修改一个state可能要动4,5个文件,修改复杂。

2.每次dispatch一个action都会遍历所有的reducer,重新计算connect,很费效率。

3.如果store较大时候,频繁的修改store,会明显看到页面卡顿。

4.不支持typescript。

  • thunk和saga是什么?

thunk和saga是redux的异步解决方案,thunk可以接受一个函数并且可以在里面dispath action,但是缺点是action的调用会分散在各个文件中,不易管理。saga的优点是action统一管理,集中处理异步操作,但是个人觉得saga可能初学起来不是太容易,需要先学习es6的yield和async以及await语法。

  • 什么是mobx?

mobx是一个简单的可扩展的状态管理框架。它通过@observable定一个被观察的状态数据,state的修改是在action函数中进行,并且提供了computed,通过get和set也可以计算state,它比起redux更加的简洁明了,在页面中是通过@inject("store")注入store,并且把组件@observer变为观察的组件。

  • redux和mobx的区别在哪里?

这两个框架都是可以做react状态管理的,mobx很简洁,上手很快,原理也是比较简单,从页面发起action到对应的action去处理state,大量使用了装饰器语法。不需要花大量的时间去研究即可上手编写。

redux则比较庞大一点,它的衍生出来的框架也有thunk和saga,学习saga需要学习es6的await,yield,async语法,学习成本和维护成本高一点。

redux是单数据源的,其中一个原则是单一数据源,你需要将所有的state放到一个全局的store里面,而mobx相反,它可以@observable观察多个state,也就是可以由多个数据源。

  • react的生命周期

分为4个阶段:初始化阶段,挂载阶段,更新阶段,卸载阶段

初始化阶段:

defaultProps={}:设置默认的props
constructor() :这里可以获得props和初始化state

挂载阶段:
componentWillMount() :组件被挂载到页面之前调用,这时候还无法获取dom对象。
render() :渲染组件到页面中,这里注意不要使用setState,否则会递归渲染。
componentDidMount():组件已经挂载到页面,dom也可以获得到,也可以发送ajax请求,也可以修改state状态,但是注意这里修改状态会重新渲染。

更新阶段:

componentWillReceiveProps() :组件接收到新的props会触发这个方法,修改state不会触发这个。
shouldComponentUpdate() :这个方法返回true和false,来决定是否重新渲染组件,性能优化就是在这里进行。
componentWillUpdate() :组件将要更新时候调用。
render() :重新渲染组件,这个函数能够执行多次,只要组件的属性或状态改变了,这个方法就会重新执行
componentDidUpdate():组件已经被更改过了,会调用这个方法。

卸载阶段:

componentWillUnmount():组件将要卸载时调用,一些事件监听和定时器需要在此时清除。

  • react性能优化建议

1.bind函数的使用,在constructor中bind进去,因为构造函数每次渲染只会执行一次,在jsx模版中bind会每次render都会执行。

2.shouldComponentUpdate里进行优化,这个钩子可以返回true和false,false的话就是不渲染,可以在这里面决定是否渲染组件。

3.组件继承React.PureComponent,因为它比React.Component性能更好,当props和state改变的时候,PureComponent会对它们进行浅比较,来决定是否渲染组件,而Component不会进行比较,当shouldComponentUpdate被调用时候,组件默认会重新渲染。

4.使用redux和mobx这些框架来管理状态。

5.props尽量只传递需要的数据,多余的就尽量不要代入过去了。

6.如果有组件循环,需要指定key。

  • react是怎么检测数据变化?

react是单向数据流,所以不像vue和angular一样可以自动实现检测到数据变化,react是需要主动触发数据变化,比如setState时候,就可以触发更新。

VueJs相关

  • vue是什么?

vue是一套用于构建用户界面的渐进式框架,它的核心是数据驱动和组件化。

代码简洁体积小,运行效率高,上手快。

  • 什么是渐进式框架?

我们可以只用我们想要的一部分功能,非侵入性的,而不是必须强制注入其他不相关的依赖。

  • 简述vue响应式原理?

当vue的实例被创建的时候,Vue 将遍历data中所有的属性,并使用Object.defineProperty劫持将它们全部转为getter/setter,vue追踪它们内部的相关依赖,在属性被访问和修改时候通知变化。

每个组件都对应一个watcher实例,它会在组件渲染过程中把接触过的属性记录为依赖,之后当依赖项的setter触发时候,会通知watcher,使关联的组件会重新渲染。

弊端:1.劫持需要递归遍历消耗比较大。2.对新增和删除属性没有数据劫持的,无法监听到,需要用vue.$set().3.数组的一些方法也不能监听到,比如数组的filter(),concat(),slice()

  • Vue3响应式原理?

主要是使用了es6的Proxy来对数据进行代理拦截,Proxy对象接受两个参数,target和handler,handler可以对对象进行一些拦截处理,提供了有get,set,has,apply,construct,deleteProperty、defineProperty等13种方法。

通过判断当前的Reflect.get返回值是Object类型,则再通过reactive方法做代理,这样就实现了深度观测。

  • vue框架的优点?

    (1)轻量级框架:只关注视图层,大小只有几十Kb;
    (2)简单易学:文档通顺清晰,语法简单;
    (3)数据双向绑定,数据视图结构分离,仅需操作数据即可完成页面相应的更新;
    (4)组件化开发:工程结构清晰,代码维护方便;
    (5)虚拟 DOM加载 HTML 节点,运行效率高。

  • Vue如何监测数组变化的?

同样也是通过Object.defineProperty数据劫持,引起数组变化的方法有pop,push,shift,unshift,splice,sort,reverse这7种。Vue重写了数组的原型方法,在调用数组这几个方法改变数组时候能被监测到,然后相关依赖的视图内容会更新了。

  • Vue的事件绑定原理?

1.原生dom的绑定:在updateDOMListeners方法里面,对原生的dom元素用addEventListener方法来添加事件

2.组件绑定事件采用的是Vue中的$on方法

  • vue的生命周期?

分为4个步骤,创建,挂载,更新,销毁

1.创建

beforeCreate();

created(); // 初始化的内容写在这里,比如请求ajax进行数据处理

2.挂载

beforeMount();

mounted(); // dom渲染在这里就已经完成了,可以获取到dom节点

3.更新

beforeUpdate();

updated();

4.销毁

beforeDestroy();

destroyed();

第一次页面加载会触发:beforeCreate,created,beforeMount,mounted这几个钩子函数,而且dom渲染在mounted中就已经完成了。

  • vue中的$nextTick()的理解?

在vue的created()钩子中操作dom,需要用到$nextTick()这个函数,因为这时候dom元素还没有渲染完毕,我们取dom元素是取不到的,这个函数是可以在dom更新之后,把操作放到它的回调函数里。它其实就是一个异步任务来做延迟,底层是使用了event loop中的微任务和宏任务,做了设备api的兼容,如果支持Promise,会优先使用Promise.then(微任务)来实现延迟,如果不支持就用普通的setTimeout(宏任务)来实现了。

  • vue怎么监听键盘事件?

直接在生命周期里绑定document.οnkeydοwn=function(e){}即可。

监听事件除了keycode对应的数字之外,vue还添加了事件的别名,比如enter,tab,delete,esc,space等。

  • vuex是什么?

vuex是一个专门为vuejs设计的状态管理工具,在状态比较多难以管理的时候就用它。

state:状态数据,可以通过modules来配置多个数据源操作。

getter:返回计算处理state后的函数,相当于vue中的计算属性。

mutations:真正处理state的地方,并且mutation必须是同步函数。

action:用户提交的action操作,view 层通过 store.dispath 来调用 action。Action提交的是mutation,而不是直接变更状态,Action可以包含任意异步操作。

modules:如果管理状态的业务比较复杂,可以分为几个模块,最后在vuex中使用模块,引用的时候加上模块的名字即可。比如:

const moduleA = {
  state: { name:'this is a name' },
  mutations: {  },
  actions: {  }
}
const store = new Vuex.Store({
  modules: { moduleA }
})
this.$store.state.moduleA.name; // 使用的时候加上模块的名称

流程是;用户在view上dispatch一个action》vuex的actions接收到数据后commit到mutations》mutations更改state的数据状态》可以通过vuex提供的getters展示到view,也可以在view里this.$store.state.text来获取状态数据。

  • vuex中的异步修改怎么实现?

需要在action中做异步处理,不在mutation中处理是因为vuex官网上也有说,mutation是必须是同步的函数,mutation操作写异步的话状态很难追踪,这样就会造成很多问题。Action和Mutation的区别是,action提交的是mutation,而不是直接操作state,action中是可以包含任何异步的操作。在action中同步就需要return new Promise(),或者是使用async来定义action,这样在异步处理的时候才会同步去执行。

  • Promise是什么?

Promise是异步处理的一种解决方案,多个异步的处理不需要通过回调函数来处理,es6提供的promise处理后可以返回一个resolve,异步执行完后执行resolve()就会执行then里面的代码,这样使异步不再变得不可控,甚至可以多个then链式调用来控制异步代码的执行顺序。

Promise中有3种状态:

pending:初始状态,既不是成功也不是失败

 fulfilled:意味着操作完全成功

 rejected:意味着操作失败

同一时间只有一个状态存在,且状态改变就不能再变了,当调用resolve()时候会执行后面的then,当执行reject()就不会继续进行下去。

  • vuex如何缓存,在页面刷新时候不丢失

登录等信息存储的数据保存到sessionStorage中最好,长久保存的信息保存到localStorage中,当刷新页面时候,重新合并获取到的数据到store中。

  • vue模板编译原理?

参考:https://segmentfault.com/a/1190000013763590

1.解析器将模板字符串转换成AST抽象语法树(Abstract Syntax Tree)

2.对AST抽象语法树进行静态节点标记(主要用来做虚拟DOM的渲染优化,标记静态节点好处是:每次重新渲染,不需要为静态节点再创建新的,可以跳过虚拟DOM中patching打补丁的过程)

3.代码生成器会将AST生成render函数代码字符串

4.render函数的返回值就是vnode虚拟节点

  • Vue中的diff算法

diff算法是比较虚拟dom差异的一个算法,它可以对虚拟dom进行逐层的比较,如果树类型不同,就会重新创建,如果类型相同,属性不同,就会只更新属性不同的部分,如果在子节点后新增节点,会直接增加节点,如果在子节点前增加节点,会重新生成这几个节点,而且diff在比较新旧节点的时候,只会同级进行,不会跨层级比较。

  • vue和react的区别?

相同点:

1.都可以做spa单页面应用。

2.都支持服务器端渲染

3.都有Virtual Dom,页面的操作数据会反应到虚拟dom上,通过diff算法计算后再渲染到页面。

4.都有组件,都有props,并且支持父子组件之间通信,也都有状态管理工具,react的redux,mobx和vue的vuex。

5.都有生命周期。

不同点:

1.react是mvc框架,vue是mvvm框架。

2.react是单向数据流,用事件来操作数据改变状态,vue是双向数据绑定,通过数据劫持和订阅者观察者来实现。

3.写法不同,react用的是jsx模版,vue就像是写一个普通HTML页面一样,同时可以包含有css和js。两者在渲染数据,更改data是不一样的写法,react渲染是必须return元素在下面引用,vue是直接在标签上用指令就可以,react用setState设置数据,vue直接用等号就可以。

4.数据发生改变,vue会自动跟踪组件的依赖 关系,不需要重新渲染组件数。而react则状态改变,全部组件都会重新渲染,所以需要在shouldComponentUpdate这个生命周期里来优化

  • vue中更新数组时,可以触发视图更新的方法有哪些?

会更新视图的方法:push(),pop(),shift(),unshift(),splice(),sort(),reverse(),还可以使用Vue.set( target, key, value )

不会更新视图的方法:filter(),concat(),slice()

  • mvc和mvvm的区别?

mvc:(Model模型-View视图-Controller控制器),mvc是最经典的开发模式之一,流程是用户操作,view层负责接收输入,然后到Controller控制层,对Model数据进行处理,最后将结果通过View反馈到用户。mvc的通信是单向的,简单说就是:

用户-View-Controller-Model-Controller-View,缺点是:M和V层耦合度高,所有逻辑都在C层,导致庞大难以维护。

mvvm:(Model模型-View视图-ViewModel视图模型),也就是数据双向绑定模型,Model和View之间解耦,通过ViewModel进行交互,它就是一个同步View和Model的对象,View和Model之间的同步是自动的,不需要人为干涉,开发者只需要关注业务逻辑,不需要手动操作Dom。

  • vue中的keep-alive是什么?

概念:它是vue的一个内置组件,主要作用是可以缓存组件,避免重新渲染。

它是一个抽象组件,不会被渲染到真实DOM中,它提供了include与exclude两个属性,允许组件有条件地进行缓存。

原理:其实就是在created时将需要缓存的VNode节点保存在this.cache中,在render时,如果VNode的name符合在缓存条件(可以用include以及exclude控制),则会从this.cache中取出之前缓存的VNode实例进行展示。

  • 什么遍历的时候使用key?

因为可以给每个遍历元素添加一个唯一标识,可以让diff更快的计算出来进行渲染。

  • 怎么让css只在当前组件起作用

在当前的vue页面中的style标签纸红加上scoped即可,如:<style scoped></style>

  • vue的两个核心是什么?

数据驱动和组件化

数据驱动:简单可以解释为数据(Model)的改变,使视图(View)自动更新。也就是数据双向绑定,Model的改变会通过ViewModel改变View,同时也会监听View的变化,也会通过ViewModel响应到数据Model,实现数据双向绑定。

组件化:组件化实现了可扩展和可重用可维护的html元素,通过封装可用的代码,页面上每个独立交互的功能都可以抽取出来成一个组件。

  • vue的http请求都有哪些框架,ajax、axios、fetch之间的详细区别以及优缺点

可以参考:ajax、axios、fetch之间的详细区别以及优缺点_毛毛虫博客-CSDN博客_fetch和axios的区别

  • 为什么new vue({data:{name:''}})中data是一个对象,而在组件中,data(){return{name:''}},data必须是一个函数呢?

首先每一个组件其实都是一个vue实例化得来的,引用的是同一个实例,所以一个发生改变,其他的引用肯定也会改变的,但是换成函数的话,因为变量在函数里外部不能直接访问,所以也就不会影响到别的组件。所以new vue的时候实例其实只有一个,用data:{}也就可以了。

  • 怎么自定义一个vue的过滤器?

1.在组件中自定义过滤器

在组件中写:
filters:{
    myFilter(value){
        return value.toLowerCase();
    }
}
使用:
直接输出属性时候{{name | myFilter}}
或者在v-bind中<div v-bind:name="name | myFilter"></div>

2.自定义全局过滤器

Vue.filter('allFilter', function (value) {
  return value.toLowerCase();
})

new Vue({
  // ...
})
  • vue中自定义指令怎么写?

参考官方的文档的写法,指令是有几个钩子函数的,bind,inserted,update等,具体的含义和使用参考自定义指令 — Vue.js

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})
  • v-on可以绑定多个方法,
<div v-on="click1(),click2()")>click here</div>
  • 什么是vue中的计算属性?

1.计算属性可以用来计算模版中比较复杂的逻辑,运算,并且它需要返回一个结果。

2.计算属性监听vue中的数据依赖,只要依赖的其中一个数据变化了,就会重新计算,相当于watch监听数据一样。

3.计算属性还可以依赖其他vue实例中的数据,比如new vue实例有A和B,A可以获得B的data中的数据进行计算。

4.计算属性还可以进行缓存,只要依赖的数据没有变,再次请求也不会重新计算,而是去取的缓存。

  • vue中组件传值方式有哪些?

1.父-子:调用子组件<Child :name='name'></Child>,在子组件里使用props:{name:{type:String,default:'dd'}}来接收值。

2.子-父:调用子组件<Child @getChild="fromChild"></Child>,在子组件里this.$emit("fromChild",传父组件的值);

3.定义公用组件bus来传值,父组件用bus.$on("fromChild",fnction(data){});子组件用bus.$emit("fromChild",传的值);

4.使用Vuex来传值。

  • v-for和v-if为什么不能连用?

在Vue2.0中v-for的优先级是高于v-if的,所以遍历的时候会把v-if的元素都添加一遍又隐藏,这样是无意义的,会造成性能浪费。

在Vue3.0中v-if的优先级是高于v-for的,同样是不建议放在一起用的。

  • v-html会导致哪些问题?

1.xss攻击

2.v-html会替换标签内部的元素

  • 为什么Vue组件中的data是一个函数?

避免组件中数据互相影响,同一个组件被复用会创建多个实例对象,如果data是一个对象的话是不能每个组件的数据独立的,所以data是函数,里面的数据有独立的作用域,这样每个组件中返回的数据都是独立的。

  • vue中添加全局变量的方法?

第一种:定义一个全局变量的vue页面,在每个需要引用的页面import进来。

第二种:全局变量挂载到Vue.prototype原型上。

Vue.prototype.color="红色";
Vue.prototype.getColor=function(){return "红色";}

在vue页面中直接可以{{this.color}} {{this.getColor()}}来使用

第三种:在main.js的同级目录创建一个global.js,里面需要放到install里


exports.install = function (Vue, options) {
	Vue.prototype.getColor = function (){
		return "红色"
	};
}

 最后在main.js中Vue.use(global)即可,页面中的使用方法还是{{this.getColor()}}这样即可。

import global from './global'
Vue.use(global)

第四种:使用Vuex来做全局的变量,也可以在任何页面都能够获取。

  • vue中如何响应路由器参数的变化?

页面路由跳转时候,如果从/use/a调到/use/b,这时候组件是会复用的,不会重新创建,所以想对路由参数变化作出响应的话,就需要使用watch来监听$route对象。或者在组件中使用beforeRouteUpdate(to,from,next){}钩子函数来监听。

  • vue-router有几种导航守卫?

1.全局前置守卫:beforeEach

2.全局解析守卫:beforeResolve

3.全局后置钩子:afterEach

4.单独路由独享守卫:beforeEnter

5.组件内守卫:beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave

  •  vue-router路由跳转解析流程,当A路由跳转到B路由?

1.在A组件里调用离开守卫beforeRouteLeave

2.调用全局前置守卫beforeEach

3.在B路由配置里调用路由守卫beforeEnter

4.再执行B组件的进入守卫beforeRouteEnter

5.调用全局解析守卫beforeResolve

6.导航被确认

7.调用全局的后置钩子afterEach

8.触发DOM更新

  • vue-router配置动态路由
路由文件:
import HelloWorld from '@/components/HelloWorld.vue'
export default new Route({
  router:[
    // 动态路径参数 以冒号开头
    { path: '/user/:id', component: HelloWorld}
   ]
})
匹配的使用方法:
<router-link :to="'/user/1">hi页面</router-link>
// 会请求/user/1
this.$router.push({name:'/user',params:{id:1} })
  • vue的嵌套路由

由多个层次构成的路由就是嵌套路由,每个路由的父级定义<router-view></router-view>来显示子路由的页面,在路由配置里需要配置children:[{}]子路由的信息。

  • vue中<router-link>标签解释和包含的属性

这个标签相当于a标签,用来做路由的跳转。

to: 属性是路由的地址。

replace: 跳转后不会留下history记录。

tag :把router-link标签变为某个标签,比如li,span,等

active-class:当链接被激活的时候使用的class样式。

  • vue中路由普通加载和懒加载的写法

第一种,普通的加载方式

import Hello from 'Hello.vue'
const router = new VueRouter({
  routes: [
    { path: '/hello', component: Hello }
  ]
})

第二种,vue动态组件实现的懒加载

const router = new VueRouter({
  routes: [
    { 
       path: '/hello', 
       component:(resolve) =>{
          require(['@/components/Hello.vue'],resolve)
       }
    }
  ]
})

 第三种,es6的import实现的懒加载,推荐这种,vue-router官方也写的这种。

const Hello = () => import('@/componsnts/Hello.vue')
const router = new VueRouter({
  routes: [
    { path: '/hello', component: Hello }
  ]
})
  • vue路由的两种模式

 vue路由有两种模式,hash和history,默认是hash,前端路由的核心就是改变页面路径的同时不会向后台发送请求。

hash:地址栏有带一个#号,比如:http://www.abc.com/#/hello,刷新页面和前进后退都可以用。这个是不会请求后台的,是前端页面中使用的路由。

history:需要在路由里配置mode为history,利用了html5的history新增的 pushState() 和 replaceState() 方法方法,比如http://www.abc.com/user/1,这种请求的路径需要和后台匹配的,不然会返回404找不到资源。

  • $route和$router区别?

1.$route是路由信息对象,包括path,params,query等路由参数。

2.$router是路由实例,包括了路由的跳转方法this.$router.push(),this.$router.replace(),this.$router.go(),this.$router.back()等,和一些钩子函数router.beforeEach(),router.afterEach()等。

webpack相关

  • 什么是webpack

webpack是一个前端模块化打包工具,可以把项目中的资源打包成浏览器可以识别的资源。主要由entry入口,output出口,loader,plugins四个部分。

  • 什么是webpack中的bundle,chunk,module?

bundle:是由webpack打包出来的文件,
      chunk:是指webpack在进行模块的依赖分析的时候,代码分割出来的代码块。
    module:是指开发中的单个模块。

  • 什么是loader,plugin?

loader就是一个加载器一样,使webpack有能力处理这些非javascript类型的文件。比如处理css的less-loader,图片,字体等类型的,配置在module.rules中

plugin就是打包用到的插件,可以参与到打包的流程中,比如最常用到的htmlPlugin,可以把js和css打包到html模版文件中。

  • webpack的构建流程?

1.初始化配置参数

2.初始化compiler对象,准备编译

3.确定entry入口文件并遍历

4.使用loader和plugin编译解析文件

5.输出资源文件

  • webpack热更新原理?

大致原理:

1.启动本地服务后,服务端和客户端使用websocket作长连接;

2.webpack监听到源文件变化,然后webpack会重新编译,每次编译都会生成hash值、已改动模块的json文件、已改动模块代码的js文件;

3.编译完成后,会通过socket向客户端推送当前编译的hash;

4.客户端websocket监听到所有文件改动推送过来的hash,会和上一次的对比,一致的会走缓存,不一致的会通过ajax向服务器获取最新资源,使用内存文件系统去替换有修改内容的地方实习局部刷新。

  • webpack打包性能优化方法?

1.定位体积比较大的模块,可以用webpack-bundle-analyzer插件来查看。

2.提取公共模块。

3.移除不必要的文件。

4.可以通过cdn引入一些库文件,可以见效打包文件的体积。

5.利用缓存。

6.更换js的压缩插件为uglifyjs-webpack-plugin。

7.使用dllpllugin,这个插件可以实现把依赖的第三方的包(比如react,vue,jquery)完全分离开,因为这些第三方包不会经常改变,除非是版本升级,所以这些第三方包只需编译一次,生成*.dll.js文件,以后每次只打包项目自身的业务代码,可以提高编译速度。

8.因为webpack是单线程的,所以可以使用happypack用多个进程并行处理,可以提高打包速度。

  • webpack和gulp的区别?

webpack和gulp都是前端自动化构建工具,但是他们的定位不一样,webpack侧重于模块打包,根据模块之间的依赖,生成最终生产部署的前端资源。

gulp侧重于前端开发的流程,在gulpfile.js里通过配置task任务使用一些插件,来实现js,css压缩,图片压缩,编译less,热加载。gulp利用流的方式进行文件的处理,gulp处理的文件是写在内存中,通过管道将多个任务和操作连接起来,所以处理更快,流程更清晰。

  • webpack常用的插件

1.autoprefixer 自动补全css3的前缀

2.html-webpack-plugin  生成html文件,可以使用指定的模板html。

3.extract-text-webpack-plugin 打包时候分离css,形成独立的文件

4.copy-webpack-plugin  拷贝文件和文件夹到指定目录,也可以配置ignore忽略文件。

5.webpack.ProvidePlugin 自动配置全局加载模块,比如配置jquery,不用每次都import使用。

new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery'
})

6.HotModuleReplacementPlugin 模块热替换插件,修改可以实时看到。

7.uglifyjs-webpack-plugin webpack4中的压缩js插件

8.clean-webpack-plugin 清理打包目录插件,可以配置清理的文件夹目录

9.happypack webpack是单线程的,这个插件是可以多线程执行任务,加快编译速度

10.webpack-dev-server 启动server后,可以把打包的文件存储到内存中,这样可以使用热加载功能,修改代码不需要刷新页面。

  • webpack怎么自定义插件

webpack自定义插件可以通过es6的class写一个类,或者用函数,最后再模块导出,在webpack.config.js中new插件即可。

第一种实现方式,使用函数方式,并且在函数的原型上绑定apply方法

function MyHelloPlugin(options){
	console.log('接收插件的参数:',options)
}
MyHelloPlugin.prototype.apply = function(compiler){
	compiler.plugin('emit', function(compilation) {
		console.log('生成资源到output目录之前:',compilation);
	});
	compiler.plugin('done', function() {
		console.log('编译完成了');
	});
}
module.exports=MyHelloPlugin;


// 在webpack.config.js中引入并入使用
 const MyHelloPlugin = require('./webpack.myplugin.js')
 new MyHelloPlugin({option:true})

第二种方式,使用class,并在里面添加apply方法

 class MyHelloPlugin{
	constructor(options){
		console.log('传递的参数:',options)
	}
	apply(compiler){
		compiler.plugin('done',function(compilation){
			console.log('编译完成')
		})
	}
}
module.exports=MyHelloPlugin;

// 在webpack.config.js中引入并入使用
 const MyHelloPlugin = require('./webpack.myplugin.js')
 new MyHelloPlugin({option:true})

以上两种方式都可以,但是必须要写apply方法,因为自定义插件运行的时候会自动应用插件对象绑定的这个apply方法。

apply方法的回调返回一个compiler对象,这个对象是继承自Tapable类,compiler可以监听整个编译的过程,它里面包含整个webpack声明周期钩子,比如有beforeRun,watchRun,run,beforeCompile,compile,compilation,emit,afterEmit,done,watchClose等等钩子。

Tapable这个类暴露很多的钩子函数,compiler中的钩子其实用到的是这里面的,比如写插件需要的plugin方法,apply方法都是继承的tapable里面。这个类的作用实际上就是一个事件管理器,是一个基于发布订阅者的模式,专注于事件的触发和处理。

compiler的钩子的回调是返回一个Compilation对象,这个对象是继承Compiler,它的主要作用是在打包的过程中可以获得打包的模块和依赖,同时也提供了一些钩子函数,在这个阶段模块可以被加载(loaded),封存(sealed),优化(optimized),分块(chunked),哈希(hashed),重新创建(restored),当然它也是属于compiler声明周期中的一个钩子。

Koa相关

  • koa中的koa-body是什么?

是koa中的一个插件,可以处理请求和实现上传文件等操作,可以代替请求处理的koa-bodyparser和图片文件上传的koa-multer。

Nodejs相关

  • 什么是PM2?

pm2是一个node进程管理器,可以利用它来简化很多node应用管理的繁琐任务,如性能监控、自动重启、负载均衡等。

Web相关

  • 理解web标准,了解可用性,可访问性和安全性

web标准是一些列标准的集合,主要包括 结构表现行为

结构标准:是指用html,xhtml,xml来描述页面的结构。

表现标准:是指使用css样式来美化页面结构,使它更具有美感。

行为标准:是指用户和页面之间有一定的交互,可以使页面结构和表现发生改变,比如W3c制定的EcmaScript标准来实现。

可用性:是指页面从用户的感官上来说是否容易上手,容易理解,容易操作完成,可用性好说明产品质量高。

可维护性:是指系统出现问题时候可以快速定位解决,成本低,可维护性高,而且代码结构是否清晰符合标准,让其他的开发者更容易上手维护。

可访问性:是指在不同浏览器,不同屏幕下是否可以很好的去展示,并且对不同的用户或者有残疾的用户是否都可以使用。

  • 什么是html语义化?

使用语义适当的标签去构建html页面的结构,比如使用h1-h6设置标题,使用header,footer,nav,aside标签来划分结构。html语义化可以使html的页面结构变得更加清晰,即使没有css的情况下页面也能够很好的呈现出结构,还能提升用户体验,方便维护,方便爬虫抓取和seo搜索引擎优化,也便于不同设备之间的访问。

  • 什么是响应式网页设计?

网页可以在不同尺寸的设备上面可以自动调整显示和布局,以适应不同尺寸屏幕的浏览体验。

  • web安全及防护

1.sql注入:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

2.xss攻击:指的是攻击者往Web页面里注入恶意脚本代码,当用户浏览网页时候执行恶意代码来窃取用户的信息。

3.csrf攻击:指的是打开未受信任的网站,导致本地存储的cookie和个人信息泄露,而造成的被盗用了个人信息。比如你刚转了钱,本地保存了你的银行的个人信息,接着你又不小心访问了一个网站,这个网站就会盗取你的信息,去盗取你的银行信息。

  • web性能优化有哪些?

优化的目的:

    用户角度:网页加载速度快,操作响应及时,用户体验好。

    服务商角度:能减少页面请求、和占用的带宽资源,提高服务器的处理响应速度。

主要分为:

①页面级别优化

1.减少http请求。

2.使用外部脚本和css,可以缓存下来。

3.打包资源优化。

4.避免请求重复的资源,减少不必要的http跳转。

5.按需加载资源,比如js和图片懒加载。

6.从设计层面上简化页面,避免过于复杂的交互操作。

7.把js放到底部,把css放到header,可以避免造成阻塞。

8.使用骨架屏,可以用base64图片代替展示,数据加载完了就替换当前图片。

②代码级别优化

1.减少dom的操作,避免重绘和回流而影响页面性能。

2.减少闭包的使用,因为闭包的变量都会在内存中,过多会造成内存消耗。

3.css优化,减少使用行内标签,可以用类和标签选择器,同样的功能建议抽取出来一个common css。

4.在手机端的页面,可以添加样式transform:transition3d(0,0,0)来开启硬件加速,会使页面流畅。

5.避免大量的声明全局变量,因为这些变量会绑定到window全局变量上,会可能造成内存溢出。

③服务器优化

1.提高硬件环境。

2.优化nginx,比如加大进程数,配置gzip压缩减少网络上所传输的数据量,配置超时时间,缓存等

  • 移动端性能优化有哪些?

1.尽量使用css3的动画开启硬件加速,比如transform:transition3d(0,0,0)。

2.使用touch事件代替click事件。

3.避免使用css3的阴影效果。

4.不滥用float,因为float在渲染时候计算了比较大,会影响性能。

5.不滥用web字体,web字体需要下载,解析,重绘,尽量减少使用。

6.pc端的性能优化同样适用在手机端。

  • 什么是web语义化?

Web语义化是指使用语义恰当的标签,使页面有良好的结构,页面元素有含义,能够让人和搜索引擎都容易理解。比如使用footer,body,header,section标签等,好处是便于阅读和理解,便于爬虫抓取和搜索引擎优化。

  • 什么是前端模块化?

可以理解为一组自定义业务的抽象封装,是根据项目的情况来进行封装组合到一起的,比如我们可以分为登录模块,评论模块。模块可维护性好,组合灵活,方便调用,多人协作互不干扰。因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。

  • 什么是前端组件化?

指对具体的某个功能的封装,比如所有的分页可以封装为分页组件来统一使用,以此来达到组件复用,提高开发效率。

  • 什么是前端工程化?

概念:指使用软件工程的技术和方法来进行前端项目的开发、维护和管理。

前端工程化包含如下:

1.代码规范: 保证团队所有成员以同样的规范开发代码。

2.分支管理: 不同的开发人员开发不同的功能或组件,按照统一的流程合并到主干。

3.模块管理: 一方面,团队引用的模块应该是规范的;另一方面,必须保证这些模块可以正确的加入到最终编译好的包文件中。(以上两点可以总结为模块化或者组件化开发。)

4.自动化测试:为了保证和并进主干的代码达到质量标准,必须有测试,而且测试应该是自动化的,可以回归的。

5.构建:主干更新以后,自动将代码编译为最终的目标格式,并且准备好各种静态资源,

6.部署。 将构建好的代码部署到生产环境。

  • 什么是spa单页面应用?

spa(single page web application)单页面应用,就是只有一个Web页面的应用,浏览器一开始会加载所需要的HTML、CSS和js资源,所有的操作通过js来动态更新该页面,这样的程序就叫做spa单页面应用。
优点:

1.用户体验好,避免不必要的跳转页面和重复渲染。

2.减轻服务器端压力。

3.前后端分离,各司其责,便于优化管理。

缺点:

1.不利于seo搜索优化。(可以通过ssr服务器端渲染等方法)

2.首屏加载时间过长。

  • 什么是SSR服务器端渲染?

就是在服务器端生成页面的html,再发送到浏览器。与单页面应用相比,服务器端渲染更好的利于seo搜索优化,和减少首页加载时间。但是同时也存在缺点,比如学习成本比较大,也会加大服务器的压力。

网络协议相关

  • http协议的介绍

http协议(Hyper Text Transfer Protocol超文本传输协议),是一个应用层的协议。

  • http的特点是?

1.支持客户端/服务器模式,也就是请求/响应的模式。

2.简单快速:是说我们只需要指定get,post,head这些请求方式和访问路径,就可以进行访问了。

3.灵活:是指现在的版本中可以传输任意的数据,文件,xml,json都可以,只需要指定content-type对应的类型即可。

4.无连接:是指每次链接只处理一个请求,服务器处理完请求后,响应给客户端并收到客户的应答后就断开链接。

5.无状态:是说http协议对事务的处理没有记忆能力,如果中断了,就必须要重新传输了。

  • http每个版本的区别有哪些?

http有4个版本,http/0.9,http/1.0,http/1.1,http/2.0。

1.http/0.9:在1991年发布,是http协议最初的版本,功能简陋,只支持get的请求方式,也不支持请求头,服务器只能返回html格式的字符串。

缺点:功能比较简陋,只能处理get请求,返回类型比较少。

2.http/1.0:在1996年发布,比0.9支持了很多的内容;

①支持get,post,head请求

②支持请求头和响应头,状态码,缓存,内容编码。

③服务器响应对象不仅限于超文本了,content-type可以设置更多的格式,图片,视频等。

④新建一个tcp连接,只能发送一个请求,服务器也只能处理一个请求。

⑤部分浏览器支持connection:keep-alive;长连接,可以在请求结束后服务器不关闭连接。

缺点:tcp连接新建需要三次握手,每个tcp连接只能发送一个请求,而且发送后服务器就会断开此次连接,这样的处理比较耗费效率,也没办法复用。虽然也有一些浏览器实现了Connection:keep-alive;长连接,但是并不是每个浏览器都支持这个。

3.http/1.1:在1997年发布,添加了很多优化性的内容;

①支持持久连接,不用声明Connection: keep-alive;tcp新建连接后默认不关闭,可以被对个请求复用。客户端也可以主动在最后一个请求发送Connection:close;来关闭连接。

②支持在一个tcp连接里,支持客户端可以同时请求多个连接,但是服务器还是需要按照顺序来处理,谁先发送的就先处理谁。

③新增了多个请求的方法,options,put,delete,connect,trace。

④新增了一些状态码,身份认证机制,支持文件断点续传。

⑤添加了一些cache的新特性,增加Cache-control属性。

缺点:虽然支持多个请求,但是在服务器端需要排队处理,会出现请求堵塞的情况。消息头部无法压缩,比较占字节,会浪费一些网络资源。

4.http/2.0:在2015年发布,在谷歌,ie11以及火狐等现代浏览器已经可以支持http/2.0协议了;

①二进制协议,在http1.1里是超文本传输协议,http2.0已经可以支持二进制协议了,体积更小,易于解析不会出错。

②真正的多请求处理,客户端请求多个到服务器端,在服务器端处理是可以多对多的,也不用服务器按照请求的顺序去处理,即使某个请求堵塞了也不会影响到其他的请求处理。

③解决了http1.1的请求头部压缩问题,加快请求传输速度。

④服务器推送,服务器可以主动向客户端推送资源,资源包括页面,css,js,图片等资源,客户端检测到后解析处理,这样这些资源已经在本地了,浏览器可以更快的拿到而不是再通过网络重新请求,这样减少了客户端去请求服务器再到服务器响应的过程,大大提高了效率和资源的利用。

1.https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。

2.http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

3.http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

4.http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

注:ssl是一个位于tcp和http之间的安全协议,为数据通讯提供安全支持

  • http状态码301和302的区别?

        301 redirect: 301 代表永久性转移(Permanently Moved)

        302 redirect: 302 代表暂时性转移(Temporarily Moved )

  • ETag是什么?

etag是entity tag的缩写,意思就是实体标签的意思,它是http协议中请求head中的一个属性,用来帮助服务器控制web端的缓存验证。

  • tcp和udp的区别?两个都是传输层的协议,

    ①TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接

    ②TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付

    ③UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。

    ④每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信

    ⑤TCP对系统资源要求较多,UDP对系统资源要求较少。   

  •  get和post的区别?

1.get用于获取数据,post是提交数据。

2.get提交的参数追加在url的后面,用?和&来连接,post的参数放在Request Body提交。

3.get的url会有长度限制,最多2K,post则不会限制数据大小,而且还可以设置提交的数据类型(文件,json这些)。

4.get是不安全的,因为url上参数都已经暴露了,post是安全的。

5.get的请求参数会被保存在浏览历史记录里,post则没有。

6.get请求可以被浏览器缓存,post则没有。

  • http请求的过程?

1.当我们输入某个地址后,首先需要dns域名解析这个地址,根据一系列的dns解析域名的步骤找到对应服务器的ip。

2.tcp的三次握手建立连接。

3.建立tcp的链接后发送http请求的报文,包括请求行,消息报头,请求正文这些。

4.http响应报文,包括状态行,消息报头,响应正文,浏览器得到html代码。

5.最后浏览器解析得到的html,将结果呈现给用户。

浏览器相关

  • 浏览器内核有哪些?

1.Trident: 主要是IE,一些双核浏览器也会用到,比如360浏览器,腾讯浏览器,百度浏览器

2.Gecko:现在主要有火狐

3.Webkit:苹果自主研发的内核,使用的浏览器相当多,比如safari,Google chrome,opera,以及360,腾讯这些浏览器的高速模式都是用的这个。

4.Blink:基于webkit,Google与Opera共同开发,现在google在用。

  • 渲染引擎工作流程?

1.解析html生成dom树

2.解析css生成cssom规则树

3.将dom树和cssom规则树合并在一起生成render渲染树

4.遍历render渲染树的节点开始布局,计算每个节点的位置大小信息。

5.将render渲染树每个节点绘制到页面来显示。

注意:渲染的时候回出现阻塞的情况,当浏览器碰到script标记时候,dom构建将暂停,直到脚本执行完毕,所以要把脚本放到最下面,避免阻塞。css的话要放在最上面。

  • 什么是重绘(repaint)和回流(reflow)

重绘:当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如添加个背景色,设置个文字颜色,则就叫称为重绘。

回流:当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。

回流何时发生:

当页面布局和几何属性改变时就需要回流。下述情况会发生浏览器回流:

1、添加或者删除可见的DOM元素;

2、元素位置改变;

3、元素尺寸改变——边距、填充、边框、宽度和高度

4、内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;

5、页面渲染初始化;

6、浏览器窗口尺寸改变——resize事件发生时;

注意:回流必定触发重绘,重绘不一定触发回流,重绘的开销比较小,回流的代价比较高。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值