2021年最常见前端面试问题以及答案参考(持续更新...)

目录

欢迎访问我的个人博客:https://www.gaoyuan.ink,一起共勉学习~

开放性的题目

1.自我介绍

2.平时是如何学习前端开发的

3.未来三到五年的规划是怎样的

4.说一下web产品开发的流程

HTML合集

问题:说一说你对Doctype的理解

问题:HTML新特性

问题:说一下webworker(html5新特性)

问题:HTML5 Canvas元素有什么用?

问题:Canvas和SVG图形的区别是什么?

问题:src与href的区别

CSS合集

问题:css3有哪些新特性?

问题:CSS选择符有哪些?哪些属性可以继承?

问题:介绍一下 CSS 的盒子模型?

问题:box-sizing有那些值,有什么区别?

问题:水平垂直居中

问题:请解释一下为什么需要清除浮动?清除浮动的方式

vue合集

问题:vue生命周期函数

问题:vue响应式原理

问题:vue父子组件的生命周期

问题:vue的组件通信

JS合集

问题:JavaScript原型,原型链 ? 有什么特点?

问题:谈谈This对象的理解。

问题:null,undefined 的区别?

问题:JS 深浅拷贝

问题:遍历对象的6种方法(es6)

问题:防抖和节流

问题:闭包的概念

浏览器原理

问题:前端页面有哪三层构成,分别是什么?作用是什么?

问题:你知道TCP协议、IP协议、HTTP协议分别在哪一层吗?

问题:请说出三种减少网页加载时间的方法

问题:什么情况下会遇到跨域问题

问题:宏任务和微任务


欢迎访问我的个人博客:https://www.gaoyuan.ink,一起共勉学习~

开放性的题目

1.自我介绍

2.平时是如何学习前端开发的

3.未来三到五年的规划是怎样的

4.说一下web产品开发的流程

一、 项目的角色划分

如果不包括前、后期的市场推广和产品销售人员,开发团队一般可以划分为项目负责人、程序员、UI、业务(测试)这几个角色。

二、 开发工具的选取

三、 项目开发流程

 

只有每个开发人员都按照一个共同的规范去设计、沟通、开发、测试、部署,才能保证整个开发团队协调一致的工作,从而提高开发工作效率,提升工程项目质量。

 

HTML合集

问题:说一说你对Doctype的理解

DOCTYPE标签是一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档。

  1. ​声明必须处于HTML文档的头部,在标签之前,HTML5中不区分大小写
  2. ​声明不是一个HTML标签,是一个用于告诉浏览器当前HTMl版本的指令
  3. 现代浏览器的html布局引擎通过检查doctype决定使用兼容模式还是标准模式对文档进行渲染,一些浏览器有一个接近标准模型。

  4. 在HTML4.01中<!doctype>声明指向一个DTD,由于HTML4.01基于SGML,所以DTD指定了标记规则以保证浏览器正确渲染内容

  5. HTML5不基于SGML,所以不用指定DTD

问题:HTML新特性

一、语义标签

标签描述
<header>定义了文档的头部区域
<footer>定义了文档的尾部区域
<nav>定义文档的导航
<section>定义文档中的节

二、增强型表单

输入类型描述
color主要用于选取颜色
date选取日期
datetime选取日期(UTC时间)
datetime-local选取日期(无时区)
month选择一个月份
week选择周和年
time选择一个时间
email包含e-mail地址的输入域
number数值的输入域
urlurl地址的输入域
tel定义输入电话号码和字段
search用于搜索域
range一个范围内数字值的输入域

html5新增表单属性

属性描述
placehoder输入框默认提示文字
required要求输入的内容是否可为空
pattern描述一个正则表达式验证输入的值
min/max设置元素最小/最大值
step为输入域规定合法的数字间隔
height/wdith用于image类型<input>标签图像高度/宽度
autofocus规定在页面加载时,域自动获得焦点
multiple规定<input>元素中可选择多个值

 

三、音频和视频

音频:<audio src=" "></audio>

视频:<video src=" "></video>

 

四、Canvas绘图和SVG

 

五、WebSocket

WebSocket协议为web应用程序客户端和服务端之间提供了一种全双工通信机制。

特点:

(1)握手阶段采用HTTP协议,默认端口是80和443

(2)建立在TCP协议基础之上,和http协议同属于应用层

(3)可以发送文本,也可以发送二进制数据。

(4)没有同源限制,客户端可以与任意服务器通信。

(5)协议标识符是ws(如果加密,为wss),如ws://localhost:8023

问题:说一下webworker(html5新特性)

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

Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。

问题:HTML5 Canvas元素有什么用?

Canvas 元素用于在网页上绘制图形,该元素标签强大之处在于可以直接在HTML上进行图形操作,

问题:Canvas和SVG图形的区别是什么?

SVG先绘制后记忆,换句话说任何使用SVG绘制的形状都能被记忆和操作,浏览器可以再次显示

Canvas则是先绘制后忘记,一旦绘制完成你就不能访问像素和操作它

SVG对于创建图形例如CAD软件是良好的,一旦东西绘制,用户就很难操作它

Canvas则用于绘制和遗忘类似动漫和游戏的场画。为了之后的操作,

SVG需要记录坐标,所以比较缓慢。因为没有记住以后事情的任务,所以Canvas更快。

问题:src与href的区别

href 是指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,用于超链接。

src是指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。

CSS合集

问题:css3有哪些新特性?

  • 1)CSS3 实现圆角(border-radius:8px;),
  • 2)阴影(box-shadow:10px),
  • 3)对文字加特效(text-shadow),
  • 4)线性渐变(gradient),
  • 5)transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);//旋转,缩放,定位,倾斜 ,
  • 6)增加了更多的 css 选择器 ,
  • 7)多背景 rgba

问题:CSS选择符有哪些?哪些属性可以继承?

1.id选择器( # myid)

2.类选择器(.myclassname)

3.标签选择器(div, h1, p)

4.相邻选择器(h1 + p)

5.子选择器(ul > li)

6.后代选择器(li a)

7.通配符选择器( * )

8.属性选择器(a[rel = “external”])

9.伪类选择器(a:hover, li:nth-child)

 

不可继承的:baidisplay、dumargin、border、padding、background、height、min-height、max- height、width、min-width、max-width、overflow、position、left、right、top、 bottom、float、clear、table-layout、vertical-align、page-break-after、 page-bread-before和unicode-bidi。

可继承的:

所有子元素可继承:visibility和cursor、z-index。

内联元素可继承:letter-spacing、word-spacing、white-space、line-height、color、font、 font-family、font-size、font-style、font-variant、font-weight、text- decoration、text-transform、direction。

块状元素可继承:text-indent和text-align。

列表元素可继承:list-style、list-style-type、list-style-position、list-style-image。

表格元素可继承:border-collapse。

问题:介绍一下 CSS 的盒子模型?

1)有两种,IE 盒子模型、标准 W3C 盒子模型;

IE 的 content 部分包含了 border 和 padding;

2)盒模型:内容(content)、填充(padding)、边界(margin)、边框(border)

 

CSS盒模型和IE盒模型的区别:

  • 标准盒子模型中,width 和 height 指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。

  • IE盒子模型中,width 和 height 指的是内容区域+border+padding的宽度和高度。

问题:box-sizing有那些值,有什么区别?

box-sizing是CSS3新增属性,可调整盒子模型的样式。

box-sizing:border-box表示盒模型基于IE的盒模型,width和height决定盒模型的content区、padding区和border区。

box-sizing:content-box表示盒模型基于标准盒模型,width和height只决定盒模型的content区

box-sizing:inherit表示继承自父元素。

问题:水平垂直居中

/*已知容器的宽高 设置层的外边距*/
div {
 position: relative;		/* 相对定位或绝对定位均可 */
 width:500px;
 height:300px;
 top: 50%;
 left: 50%;
 margin: -150px 0 0 -250px;     	/* 外边距为自身宽高的一半 */
}

/*不知宽高-水平垂直居中 利用 `transform` 属性*/
div {
 position: absolute;		/* 相对定位或绝对定位均可 */
 width:500px;
 height:300px;
 top: 50%;
 left: 50%;
 transform: translate(-50%, -50%);
}

/*利用flex布局*/
.container {
 display: flex;
 align-items: center; 		/* 垂直居中 */
 justify-content: center;	/* 水平居中 */
}

/*让绝对定位的div居中*/
div {
 position: absolute;
 width: 300px;
 height: 300px;
 margin: auto;
 top: 0;
 left: 0;
 bottom: 0;
 right: 0;
}

问题:请解释一下为什么需要清除浮动?清除浮动的方式

清除浮动是为了清除使用浮动元素产生的影响。浮动的元素,高度会塌陷,而高度的塌陷使我们页面后面的布局不能正常显示。

1、父级div定义height;

2、父级div 也一起浮动;

3、浮动元素的父级div定义伪类:after , clear:both用来闭合浮动的

&::after,&::before{
  content: " ";
  visibility: hidden;
  display: block;
  height: 0;
  clear: both;
}

 

vue合集

问题:vue生命周期函数

beforeCreate( 创建前 )

created(创建后)

beforeMount(挂在前)

mounted(挂载后)

beforeUpdate(数据更新前调用)

updated(更新后)

beforeDestroy(实例销毁前)beforeUnmount

destroyed(实例销毁后) unmounted

activated(被 keep-alive 缓存的组件激活时调用)

decactived(被 keep-alive 缓存的组件停用时调用)

问题:vue响应式原理

实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调

问题:vue父子组件的生命周期

一、加载渲染过程

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

二、子组件更新过程

父beforeUpdate->子beforeUpdate->子updated->父updated

三、父组件更新过程

父beforeUpdate->父updated

四、销毁过程

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

 

问题:vue的组件通信

1.方法一:props$emit

父组件通过props向下传递数据给子组件,子组件通过event给父组件发送消息,实际上就是子组件把自己的数据发送给父组件。

2.方法二:$attrs$listeners

第一种方式处理父子组件之间的数据传输有一个问题:如果父组件A下面有子组件B,组件B下面有组件C,这时如果组件A想传递数据给组件C怎么办呢? 如果采用第一种方法,我们必须让组件A通过prop传递消息给组件B,组件B在通过prop传递消息给组件C;要是组件A和组件C之间有更多的组件,那采用这种方式就很复杂了。Vue 2.4开始提供了$attrs和$listeners来解决这个问题,能够让组件A之间传递消息给组件C。

<!--组件C-->
<template>
	<div>
 		<input type="text" v-model="$attrs.messagec" @input="passCData($attrs.messagec)">
  </div>
</template>

<script>
	export default {
    name: 'C',
    data () {
      return {}
    },
    methods:{
      passCData(val){
        //触发父组件A中的事件,把从A得到的数据hello C还给A组件
        this.$emit('getCData',val)
      }
   	}
  }
</script>
<!--组件B-->
<template>
	<div>
    <input type="text" v-model="mymessage" @input="passData(mymessage)">
    <!-- C组件中能直接触发getCData的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 -->
    <!-- 通过v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的) -->
    <C v-bind="$attrs" v-on="$listeners"></C>
  </div>
</template>

<script>
	export default {
    name: 'B',
    props:[
      message:{
      	type: String,
      	default: null
      }
    ],//得到父组件A传递过来的数据,hello B
    methods:{
      passData(val){
        //触发父组件中的事件,把message给组件A
        this.$emit('getChildData',val)
      }
    }
  }
</script>
<!--组件A-->
<template>
	<div>
    <p>this is parent compoent!</p>
    <B 
     :messagec="messagec" 
     :message="message" 
     :getCData="getCData"
     :getChildData="getChildData"></B>
  </div>
</template>

<script>
	export default {
    name: 'A',
    data(){
      return {
        message:'hello B',
        messagec:'hello C' //传递给c组件的数据
      }
    },
    methods:{
      getChildData(val){
        console.log('这是来自B组件的数据',val) //打印hello B
      },
      //执行C子组件触发的事件
      getCData(val){
        console.log("这是来自C组件的数据:", val) //打印hello C
      }
    }
  }
</script>

3.方法三:provideinject

在 Vue.js 的 2.2.0+ 版本中添加加了 provide 和 inject 选项。他们成对出现,用于父级组件向下传递数据。

父组件中通过provide来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provide中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。

<!--父组件-->
<template>
  <div>
    <p>this is parent compoent!</p>
    <child></child>
  </div>
</template>

<script>
	export default {
    name: 'parent',
    provide: {
      forChidrenData:'这是要个子组件的数据'
    },
    data(){
      return {
        message:'hello'
      }
    }
  }
</script>



<!--子组件-->
<template>
  <div>
    <input type="text" v-model="mymessage">
  </div>
</template>

<script>
	export default {
    name: 'child',
    inject:['forChidrenData'], //得到父组件传递过来的数据
    data(){
      return {
        mymessage:this.forChidrenData
      }
    }
  }
</script>

4.方法四:vuex处理组件之间的数据交互

如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。

5.方法五:中央事件总线

如果两个组件不是父子关系呢?这种情况下可以使用中央事件总线的方式。新建一个Vue事件bus对象,然后通过bus.$emit触发事件,bus.$on监听触发的事件。

公共事件总线eventBus的实质就是创建一个vue实例,通过一个空的vue实例作为桥梁实现vue组件间的通信。它是实现非父子组件通信的一种解决方案。

<!--兄弟组件A-->
<template>
  <div>
    <p>this is brother1 compoent!</p>
    <input type="text" v-model="mymessage" @input="passData(mymessage)">
  </div>
</template>

<script>
	export default {
    name: 'brother1',
    data(){
      return {
       	mymessage:'hello brother1'
      }
    },
    methods:{
      passData(val){
        //触发全局事件globalEvent
        bus.$emit('globalEvent', val)
      }
    }
  }
</script>


<!--兄弟组件B-->
<template>
  <div>
    <p>this is brother2 compoent!</p>
    <p>brother1传递过来的数据:{{brothermessage}}</p>
  </div>
</template>

<script>
	export default {
    name: 'brother2',
    data(){
      return {
        brothermessage:''
      }
    },
    mounted(){
      //绑定全局事件globalEvent
      bus.$on('globalEvent',(val)=>{
        this.brothermessage = val;
      })
    }
  }
</script>



//中央事件总线
var bus=new Vue();
var app=new Vue({
  el:'#app',
  template:`
    <div>
      <brother1></brother1>
      <brother2></brother2>
    </div>
  `,
   beforeDestroy(){
sd     bus.$off('globalEvent')
  }
})

6.方法六:$parent$children

Vue.component('child',{
  props:{
    value:String, //v-model会自动传递一个字段为value的prop属性
  },
  data(){
    return {
      mymessage:this.value
    }
  },
  methods:{
    changeValue(){
      this.$parent.message = this.mymessage;//通过如此调用可以改变父组件的值
    }
  },
  template:`
    <div>
      <input type="text" v-model="mymessage" @change="changeValue">
    </div>`
})
  
Vue.component('parent',{
  template:`
    <div>
      <p>this is parent compoent!</p>
      <button @click="changeChildValue">test</button >
      <child></child>
    </div>
  `,
  methods:{
    changeChildValue(){
      this.$children[0].mymessage = 'hello';
    }
  },
  data(){
    return {
      message:'hello'
    }
  }
})

var app=new Vue({
  el:'#app',
  template:`
    <div>
      <parent></parent>
    </div>
  `
})

JS合集

问题:JavaScript原型,原型链 ? 有什么特点?

每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,
 如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,
 于是就这样一直找下去,也就是我们平时所说的原型链的概念。
 关系:instance.constructor.prototype = instance.__proto__

 特点:
 JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。


  当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的话,
  就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象。
 	function Func(){}
 	Func.prototype.name = "Sean";
 	Func.prototype.getInfo = function() {
 	  return this.name;
 	}
 	var person = new Func();//现在可以参考var person = Object.create(oldObject);
 	console.log(person.getInfo());//它拥有了Func的属性和方法
 	//"Sean"
 	console.log(Func.prototype);
 	// Func { name="Sean", getInfo=function()}

问题:谈谈This对象的理解。

this总是指向函数的直接调用者(而非间接调用者);
如果有new关键字,this指向new出来的那个对象;
在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window;

 

问题:null,undefined 的区别?

null         表示一个对象是“没有值”的值,也就是值为“空”;
 undefined     表示一个变量声明了没有初始化(赋值);

 undefined不是一个有效的JSON,而null是;
 undefined的类型(typeof)是undefined;
 null的类型(typeof)是object;


 Javascript将未赋值的变量默认值设为undefined;
 Javascript从来不会将变量设为null。它是用来让程序员表明某个用var声明的变量时没有值的。

问题:JS 深浅拷贝

深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的

浅拷贝只复制指向某个对象的指针而不复制对象本身,新旧对象还是共享同一块内存。

深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象

 

深拷贝方法:

 JSON.parse(JSON.stringify(obj))//深拷贝对象

原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。

 

递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝

 

问题:遍历对象的6种方法(es6)

1、使用Object.keys(),Object.values()遍历 (返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)).

Object.keys(obj).forEach(key=>{
  console.log(key, obj[key])
})

2、for … in 、for-of循环遍历对象自身的和继承的可枚举属性(含继承)(不含Symbol属性)

for(var i in obj){ 
  console.log(i,obj[i]) 
}

3、Object.getOwnPropertyNames() (比上面多了不可枚举)

4、Reflect.ownKeys 包含所有的(自身+继承的)(含Symbol属性)

 

问题:防抖和节流

(1)为什么要防抖?

  • 高频的函数操作可能产生不好的影响

  • 如:resize、scroll、mousedown、mousemove、keyup、keydown……

这种在一瞬间(短时间内)对浏览器或服务器造成了过多压力的交互就需要进行优化了,为了解决这个问题,一般有两种解决方案:

  • debounce 防抖

  • throttle 节流

(2)目的:降低一个函数的触发频率,以提高性能或避免资源浪费

(3)防抖的原理就是:你尽管触发事件,但是我一定在事件触发n秒无操作后才执行。

function debounce(func, wait) {
    var timer;
    return function () {
        clearTimeout(timer)
        timer = setTimeout(func, wait);
    }
}
(4)节流的原理很简单:如果你持续触发某个事件,特定的时间间隔内,只执行一次。

 

问题:闭包的概念

闭包就是能够读取其他函数内部变量的函数,在本质上是函数内部和函数外部链接的桥梁

function foo(params) {
    var a = 'gaoyuan';
​
    function bar() {
        console.log(a);
    }
    return bar;
}
​
var res = foo();
res(); // 高原

闭包轻松解决的经典问题:

var arr = []
for(var i = 0; i < 10; i++){
    arr[i] = function () {
        console.log(i)
    }
}
arr[0](); // 10
arr[1](); // 10
arr[2](); // 10
arr[3](); // 10
​
// 同一个上下文中创建的闭包是共用一个[[Scope]]属性的。
// 因此上层上下文中的变量`i`是可以很容易就被改变的
​
// 利用闭包来解决
var arr = []
for(var i = 0; i < 10; i++){
    arr[i] = (function (i) {
        return function () {
            console.log(i);
        }
    })(i)
}
arr[0](); // 0
arr[1](); // 1
arr[2](); // 2
arr[3](); // 3
​
//通过立即执行匿名函数的方式隔离了作用域,当执行 arr[0] 函数的时候,arr[0] 函数的作用域链发生了改变
​

浏览器原理

问题:前端页面有哪三层构成,分别是什么?作用是什么?

分成:结构层、表示层、行为层。

结构层(structural layer)
由 HTML 或 XHTML之类的标记语言负责创建。标签,也就是那些出现在尖括号里的单词,对网页内容的语义含义做出了描述,但这些标签不包含任何关于如何显示有关内容的信息。例如,P标签表达了这样一种语义:“这是一个文本段。”

表示层(presentation layer)
由 CSS 负责创建。 CSS对“如何显示有关内容”的问题做出了回答。

行为层(behaviorlayer)
负责回答“内容应该如何对事件做出反应”这一问题。这是 Javascript 语言和 DOM主宰的领域。

问题:你知道TCP协议、IP协议、HTTP协议分别在哪一层吗?

TCP协议在传输层,IP协议在网络层,HTTP协议在应用层。

问题:请说出三种减少网页加载时间的方法

1.服务器角度

采取CDN加速 开启gzip压缩 允许使用强缓存或协商缓存 增加服务器带宽

2.客户端角度

合理组织CSS、JavaScript代码位置 减少DOM操作、添加事件委托 部分操作可设置防抖和节流 对于可预见的操作采取preload或prerender的预加载 对于图片可以懒加载 合并CSS图片(精灵图/雪碧图) 减少使用iframe 资源优化打包角度

3.资源优化打包角度

使用打包工具将Js文件、CSS文件和静态文件进行恰当打包处理。

问题:什么情况下会遇到跨域问题

跨域问题来自于浏览器的同源策略,即当协议、域名、端口号任意一个不同时,都会引发跨域问题。

jsonp、CORS可以用来解决跨域问题

问题:宏任务和微任务

宏任务是由宿主发起的,而微任务由JavaScript自身发起。

在ES3以及以前的版本中,JavaScript本身没有发起异步请求的能力,也就没有微任务的存在。在ES5之后,JavaScript引入了Promise,这样,不需要浏览器,JavaScript引擎自身也能够发起异步任务了。

所以,总结一下,两者区别为:

 宏任务(macrotask)微任务(microtask)
谁发 起的宿主(Node、浏览器)JS引擎
具体事件1. script (可以理解为外层同步代码) 2. setTimeout/setInterval 3. UI rendering/UI事件 4. postMessage,MessageChannel 5. setImmediate,I/O(Node.js)1. Promise 2. MutaionObserver 3. Object.observe(已废弃;Proxy 对象替代) 4. process.nextTick(Node.js)
谁先运行后运行先运行
会触发新一轮Tick吗不会

其中比较注意的是promise的内部既包含宏任务也包含微任务,promise内部执行为宏任务,then执行为微任务

  • 15
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅岛夏风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值