2023前端面试题整理

1.节流和防抖,应用场景

节流的含义是在一定时间内,多次触发同一个事件,只执行第一次操作。

应用场景:a.鼠标不断点击触发,mousedown(单位时间内只触发一次)。

                  b. 监听滚动事件,比如是否滑到底部自动加载更多,用throttle判断。

防抖的含义是指在一定时间内,多次触发同一个事件,只执行最后一次操作。

应用场景:a.search搜索联想,用户不断输入值时,用防抖来节约请求资源。

                  b.window触发resize的时候,不断调整浏览器窗口大小会不断触发这个事件,用防抖                       来让其只触发一次。

2.闭包

闭包就是指有权访问另一个函数作用域中的变量的函数
MDN 上面这么说:闭包是一种特殊的对象。
闭包的作用域链包含着它自己的作用域,以及包含它的函数的作用域和全局作用域。闭包的注意事项
通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。但是,在创建了一个闭包以后,这个函数的作用域就会一直保存到闭包不存在为止。
我们首先知道闭包有3个特性:
①函数嵌套函数
②函数内部可以引用函数外部的参数和变量
③参数和变量不会被垃圾回收机制回收
优点:
①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)
③匿名自执行函数可以减少内存消耗
闭包的缺点就是常驻内存会增大内存使用量,并且使用不当很容易造成内存泄露。
如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。

闭包的应用场景:

  1. setTimeout
  2. 回调
  3. 函数防抖
  4. 封装私有变量

3.继承的方法

原型链继承

借用构造函数继承(伪造对象,经典继承)

实例继承(原型式继承)

组合式继承

寄生组合继承

es6继承extends

4.什么是深/浅拷贝,有哪些实现方法?

基本数据类型:string,number,blooean,undefined,null

引用数据类型:object,array,function

js数据类型分为基本数据类型和引用数据类型,基本数据类型保存的是值,引用数据类型保存的是引用地址(this指针),浅拷贝共用一个引用地址,深拷贝会创建新的内存地址。

Object.assign:对象合并(第一级属性深拷贝,第一级以下的级别属性浅拷贝)

let obj1 = { a: { b: 1}, c: 2 }

let obj2 = Object.assign({},obj1)

实现深拷贝的三种方式:

a.使用递归实现深拷贝

 //使用递归的方式实现数组、对象的深拷贝
    function deepClone(obj) {
      //判断obj是数组还是对象.
      var objClone = Array.isArray(obj) ? [] : {};
      //进行深拷贝的不能为空,并且是对象或者是"object"
      if (obj && typeof obj === "object") {
        for (key in obj) {
          if (obj.hasOwnProperty(key)) {
            if (obj[key] && typeof obj[key] === "object") {
              objClone[key] = deepClone(obj[key]);
            } else {
              objClone[key] = obj[key];
            }
          }
        }
      }
      return objClone;
    }


b.使用JSON对象实现深拷贝

/*
使用js内置JSON实现深拷贝
缺陷:无法实现对对象中方法的深拷贝
*/
function deepCloneJson(obj){
    let objJson=JSON.stringify(obj);
    let objClone=JSON.parse(objJson);
    return objClone;
}

c.通过JQuery中的extend()方法实现数组深拷贝

/*
使用JQ中的extend来实现数组深拷贝
*/
function deepCloneExtend(arr){
    let arrClone=[];//es6 
    arrClone=$.extend(true,[],arr);
    return arrClone;
}

5.slice和splice的区别

a.splice改变原数组,slice不改变原数组

b.splice除了可以删除外,还可以插入

c.splice可以传入3个参数,slice接受2个参数

let arr =[1,2,3,4,5,6]
//从第3个元素开始执行删除,删除1个,将9作为新元素从删除位置插入数组
let newArr = arr.splice(2,1,9)
console.log('newArr',newArr)//[3]
console.log('arr',arr)//[1, 2, 9, 4, 5, 6]
let arr =[1,2,3,4,5,6]
//从第三个元素开始删除,到第五个元素这里结束,不包含第五个元素
let sliceArr = arr.slice(2,4)
console.log('sliceArr',sliceArr)//[3, 4]
console.log('arr',arr)//[1, 2, 3, 4, 5, 6] 

6.对Promise的理解

a.promise的产生

promise是为解决异步处理回调金字塔问题而产生的。

b.promise的状态

Promise对象的状态不受外界影响,pending(初始状态)fufilled(成功状态)rejected(失败状态)

Promise 有以上三种状态,只有异步操作的结果可以决定当前是哪一种状态,其他任何操作都无法改变这个状态,Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,只能由 pending变成fulfilled或者由pending变成rejected。

c.promise的用法

    const promise = new Promise(function(resolve, reject) {
      // ... some code
 
      if (/* 异步操作成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });

6.v-show 和 v-if指令的共同点和不同点?

共同点:v-show 和 v-if 都能控制元素的显示和隐藏。

不同点:a. 实现本质方法不同 v-show 本质就是通过设置 css 中的 display 设置为 none,控制隐藏                 v-if 是动态的向 DOM 树内添加或者删除 DOM 元素

                b.性能比较 v-show 只编译一次,后面其实就是控制 css,而 v-if 不停的销毁和创建,故                 v- show 性能更好一点。

7.什么是虚拟DOM

虚拟DOM本质上就是JavaScript对象,是对真实的DOM抽象状态变更时,记录新树和旧树的差异,最后将差异更新到真正的DOM中。

虚拟DOM的优缺点:

优点:
保证性能下限: 虚拟DOM可以经过diff找出最小差异,然后批量进行patch,这种操作虽然比不上手动优化,但是比起粗暴的DOM操作性能要好很多,因此虚拟DOM可以保证性能下限
无需手动操作DOM: 虚拟DOM的diff和patch都是在一次更新中自动进行的,我们无需手动操作DOM,极大提高开发效率
跨平台: 虚拟DOM本质上是JavaScript对象,而DOM与平台强相关,相比之下虚拟DOM可以进行更方便地跨平台操作,例如服务器渲染、移动端开发等等
缺点:
无法进行极致优化: 在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化,比如VScode采用直接手动操作DOM的方式进行极端的性能优化。

8.v-for 中key的作用

a.key属性是DOM元素的唯一标识。当数组发生增删时, 默认需要把发生改动的项目全部进行重绘 --- 浪费资源;当添加唯一标识之后, 一旦发生 增删操作之后,重绘之前会检测新绘制的元素 和 已有的元素 是否存在相同的 key , 相同则复用 --- 不浪费。
b.没有增删操作的场景下,key没有用。

9.es6新特性:

1、let 和 const
let 表示申明变量。const 表示申明常量
常量定义了就不能改了。对象除外,因为对象指向的地址没变。
const在申明是必须被赋值。
两者都为块级作用域。
2、模板字符串
3、解构
4、函数的默认值
5、Spread / Rest 操作符,三个点…
6、箭头函数
7、for of
for of遍历的是键值对中的值
for in遍历的是键值对中的键
8、class类,原型链的语法糖表现形式
9、导入导出
导入improt
导出export default
10、promise
Promise 用于更优雅地处理异步请求。
11、async/await
比promise更好的解决了回调地狱
12、Symbol,新的基本类型
13、Set集合
存储任何类型的唯一值,即集合中所保存的元素是不重复的。类数组结构。
let arrNew = new Set(待去重的数组)

10.computed和watch

a.computed:通过属性计算而得来的属性

  1. computed内部的函数在调用时不加()。
  2. computed是依赖data的属性变化而变化的,当data中的属性发生改变的时候,当前函数才会执行,data中的属性没有改变的时候,当前函数不会执行。
  3. computed中的函数必须用return返回。
  4. 在computed中不要对data中的属性进行赋值操作。如果对data中的属性进行赋值操作了,就是data中的属性发生改变,从而触发computed中的函数,形成死循环了。
  5. 当computed中的函数所依赖的属性没有发生改变,那么调用当前函数的时候会从缓存中读取。
  6. 不支持异步操作。

b.watch:属性监听

  1. watch中的函数名称必须要和data中的属性名一致,因为watch是依赖data中的属性,当data中的属性发生改变的时候,watch中的函数就会执行。
  2. watch中的函数有两个参数,前者是newVal,后者是oldVal。
  3. watch中的函数是不需要调用的。

  4. watch只会监听数据的值是否发生改变,而不会去监听数据的地址是否发生改变。也就是说,watch想要监听引用类型数据的变化,需要进行深度监听。“obj.name”(){}------如果obj的属性太多,这种方法的效率很低,obj:{handler(newVal){},deep:true}------用handler+deep的方式进行深度监听。

  5. 特殊情况下,watch无法监听到数组的变化,特殊情况就是说更改数组中的数据时,数组已经更改,但是视图没有更新。更改数组必须要用splice()或者set.this.arr.splice (0,1,100 ) − − − − − 修 改 a r r 中 第 0 项 开 始 的 1 个 数 据 为 100 , this.set.this.arr.splice(0,1,100)-----修改arr中第0项开始的1个数据为100,this.set.this.arr.splice(0,1,100)−−−−−修改arr中第0项开始的1个数据为100,this.set(this.arr,0,100)-----修改arr第0项值为100。

  6. immediate:true 页面首次加载的时候做一次监听。

  7. 支持异步操作。

11.vue-router 有哪几种导航钩子?

  1. 全局导航钩子:router.beforeEach(to,from,next)作用:跳转前进行判断拦截、组件内的钩子、单独路由独享组件

  2. 路由独享钩子可以在路由配置上直接定义 beforeEnter

  3. 组件内的导航钩子有三种:
    beforeRouteEnter 在进入当前组件对应的路由前调用
    beforeRouteUpdate 在当前路由改变,但是该组件被复用时调用
    beforeRouteLeave 在离开当前组件对应的路由前调用

12.vuex

vuex是一个专门为vue.js开发的状态管理模式,每一个vuex应用核心就是store(仓库)。store基本上就是一个容器,它包含着你的应用中大部分的state(状态)
vuex的状态存储是响应式的,当 vue组件中store中读取状态时候,若store中的状态发生变化,那么相应的组件也会相应地得到高效更新。
改变store中的状态的唯一途径就是显示 commit(提交)mutation,这样使得我们可以方便地跟踪每一个状态的变化。

State: 定义了应用状态的数据结构,可以在这里设置默认的初始状态
Getter: 允许组件从Stroe中获取数据, mapGetters辅助函数仅仅是将store中的getter映射到计算属性。
Mutation: 唯一更改store中状态的方法,且必须是同步函数。
Action: 用于提交mutation, 而不是直接变更状态,可以包含任意异步操作。
Module: modules,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理;如果所有的状态或者方法都写在一个store里面,将会变得非常臃肿,难以维护。

13.改变this指向call、apply与bind区别:

call和apply可以自动执行,bind不会自动执行,需要手动调用
call和bind都有无数个参数,apply只有两个参数,而且第二个参数为数组

14.Vue实例的生命周期

Vue实例从创建到销毁的过程,就是生命周期。
也就是:开始创建->初始化数据->编译模板->挂载dom->数据更新重新渲染虚拟 dom->最后销毁。这一系列的过程就是vue的生命周期。所以在mounted阶段真实的DOM就已经存在了。
beforeCreate:vue实例的挂载元素el和数据对象data都还没有进行初始化,还是一个 undefined状态
created: 此时vue实例的数据对象data已经有了,可以访问里面的数据和方法, el还没有,也没有挂载dom
beforeMount: 在这里vue实例的元素el和数据对象都有了,只不过在挂载之前还是虚拟的dom节点
mounted: vue实例已经挂在到真实的dom上,可以通过对 dom操作来获取dom节点
beforeUpdate: 响应式数据更新时调用,发生在虚拟dom打补丁之前,适合在更新之前访问现有的 dom,比如手动移除已添加的事件监听器
updated: 虚拟dom重新渲染和打补丁之后调用,组成新的 dom已经更新,避免在这个钩子函数中操作数据,防止死循环。
beforeDestroy: vue实例在销毁前调用,在这里还可以使用,通过this也能访问到实例,可以在这里对一些不用的定时器进行清除,解绑事件。
destroyed:vue实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁。


15.vue路由的两种模式

1.hash模式
特点:在url地址上有#号
实现的原理:原生的hasChange事件来实现,来监听hash值的变化
window.onhaschange=function(){}
刷新页面的时候:不会去发送请求,页面不会有任何问题,不需要后端来配合

2.history模式
特点:在url地址上没有#号,比较与hash模式看起来好看一些
实现的原理:利用的是history的api 来实现的 popState() 来实现的
刷新页面的时候:会去发送请求然后会导致页面出现找不到的情况,需要后端来配合解决

16.vue的响应式原理

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

当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty() 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),

最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。

17.vue 中的 keep-alive

keep-alive 是 vue 中的内置组件,能够在组件切换过程中将状态保留在内存中,防止重复的渲染 DOM;
keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们;
设置了 keep-alive 缓存的组件,会多出两个生命周期钩子(activated 和 deactivated )


18.webpack

1、webpack的作用是什么,谈谈你对它的理解?
现在的前端网页功能丰富,特别是SPA(single page web application 单页应用)技术流行后,JavaScript的复杂度增加和需要一大堆依赖包,还需要解决Scss,Less……新增样式的扩展写法的编译工作。
所以现代化的前端已经完全依赖于webpack的辅助了。
现在最流行的三个前端框架,可以说和webpack已经紧密相连,框架官方都推出了和自身框架依赖的webpack构建工具。
react.js+WebPack
vue.js+WebPack
AngluarJS+WebPack
2、webpack的工作原理?
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。在3.0出现后,Webpack还肩负起了优化项目的责任。
3、webpack打包原理
把一切都视为模块:不管是 css、JS、Image 还是 html 都可以互相引用,通过定义 entry.js,对所有依赖的文件进行跟踪,将各个模块通过 loader 和 plugins 处理,然后打包在一起。
按需加载:打包过程中 Webpack 通过 Code Splitting 功能将文件分为多个 chunks,还可以将重复的部分单独提取出来作为 commonChunk,从而实现按需加载。把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段并按需加载
4、webpack的核心概念
Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。告诉webpack要使用哪个模块作为构建项目的起点,默认为./src/index.js
output :出口,告诉webpack在哪里输出它打包好的代码以及如何命名,默认为./dist
Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
Plugin:扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。
5、Webpack的基本功能有哪些?
代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等
文件优化:压缩 JavaScript、CSS、html 代码,压缩合并图片等
代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件
自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
6、gulp/grunt 与 webpack的区别是什么?
三者都是前端构建工具,grunt和gulp在早期比较流行,现在webpack相对来说比较主流,不过一些轻量化的任务还是会用gulp来处理,比如单独打包CSS文件等。grunt和gulp是基于任务和流(Task、Stream)的。
类似jQuery,找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作构成了一个任务,多个任务就构成了整个web的构建流程。webpack是基于入口的。
webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的Loader来处理不同的文件,用Plugin来扩展webpack功能。
7、webpack是解决什么问题而生的?
如果像以前开发时一个html文件可能会引用十几个js文件,而且顺序还不能乱,因为它们存在依赖关系,同时对于ES6+等新的语法,less, sass等CSS预处理都不能很好的解决……,此时就需要一个处理这些问题的工具。


19.原型、构造函数、实例、原型链

  • 实例
    • 通俗地讲一个对象就是一个实例
  • 构造函数
    • 通俗地讲任何一个函数只要被new使用了,那么这么函数就是构造函数;eg: new A()
    • 构造函数就是个函数,它和普通函数的唯一区别就是可以用new 创建实例,且构造函数都有contructor属性
  • 原型
    • 每个对象都有一个原型对象,对象以其原型为模板,从原型继承方法和属性,这些属性和方法定义在对象的构造器函数的prototype属性上,而非实例本身。
  • 原型链
    • 每个对象都有一个原型对象,通过__proto__指针指向上一个原型,并从中继承方法和属性,同时原型对象也会拥有原型,这样一层一层的,最终指向null,这就是原型链

20.移动端适配的五种方案

  1. @media 媒体查询
  2. 百分比布局
  3. flex布局
  4. rem实现
  5. vh、vw 方案即将视觉视口宽度 window.innerWidth 和视觉视口高度 window.innerHeight 等分为 100 份。

21.组件生命周期执行顺序 

  1. 加载渲染过程

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

  2. 子组件更新,影响到父组件的情况
    父组件 beforeUpdate -> 子组件 beforeUpdate -> 子组件 updated -> 父组件 updated

  3. 子组件更新,不影响到父组件的情况

    子组件beforeUpdate -> 子组件updated

  4. 父组件更新,不影响到子组件的情况
    父组件 beforeUpdate -> 父组件 updated

  5. 父组件更新影响到子组件的情况

    父组件beforeUpdate -> 子组件beforeUpdate -> 子组件updated -> 父组件updated

  6. 销毁过程

    父组件 beforeDestroy -> 子组件 beforeDestroy -> 子组件 destroyed -> 父组件 destroyed

22.Promise.all() 的使用 

promise.all()用于一个异步操作需要在几个异步操作完成后再进行时使用。

promise.all()接受一个promise对象组成的数组参数,返回promise对象。

当数组中所有promise都完成了,就执行当前promise对象的then方法,如果数组中有一个promise执行失败了,就执行当前promise对象的catch方法。
 

const p1 = new Promise((resolve, reject) => resolve(1))
const p2 = new Promise((resolve, reject) => resolve(2))
Promise.all([p1, p2]).then(res => console.log(res)).catch(res =>
 console.log(res));

23.宏任务和微任务

js是一种单线程语言,js中的任务按顺序一个一个的执行,但是如果一个任务耗时太长的话,后面的任务就要慢慢等待,为了解决这个问题,将任务分为了同步任务和异步任务。而异步任务又分为微任务和宏任务。

宏任务:setTimeout,setInterval,UI交互事件,I/O等。

微任务:promise.then(),Object.observe等。

24.websocket和http的区别

  1. websocket是双向通信协议,模拟socket协议,可以双向发送或者接收信息,而http是单向的;
  2. websocket是需要浏览器和服务器握手进行建立连接的,而http是浏览器发起向服务器的连接。
  3. WebSocket是HTML5规范提出的一种协议;目前除了IE浏览器,其他浏览器都基本支持。他是一种协议,万变不离其宗,也是基于TCP协议的;和HTTP协议是并存的两种协议。

25.箭头函数和普通函数的区别

  1. 箭头函数比普通函数更加简洁。
  2. 箭头函数没有自己的this。
  3. 箭头函数继承来的this指向永远不会被改变。
  4. call(),apply(),bind()等方法不能改变箭头函数中的this指向。
    var id = 'Global';
    let fun1 = () => {
        console.log(this.id)
    };
    fun1();                     // 'Global'
    fun1.call({id: 'Obj'});     // 'Global'
    fun1.apply({id: 'Obj'});    // 'Global'
    fun1.bind({id: 'Obj'})();   // 'Global'
  5. 箭头函数不能作为构造函数使用。
  6. 箭头函数没有自己的arguments。
    箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上
    获得的是它外层函数的arguments值。
    
    
  7. 箭头函数没有prototype。
  8. 箭头函数的this指向哪里?
    箭头函数不同于传统JavaScript中的函数,箭头函数并没有属于⾃⼰的this,它所谓的this
    是捕获其所在上下⽂的 this 值,作为⾃⼰的 this 值,并且由于没有属于⾃⼰的this,所以
    是不会被new调⽤的,这个所谓的this也不会被改变。

26.事件循环机制(event loop)

Event Loop 即事件循环, 是JavaScript或Node为解决单线程代码执行不阻塞主进程一种机制,也就是我们所说的异步原理。

事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。

27.语义化标签

28.keep-alive原理

keep-alive是vue中的一个内置组件,会缓存不活动的组件实例,防止重复渲染Dom。vue的缓存机制并不是直接存储dom结构,而是将dom节点抽象成了一个个vnode节点。因此,vue的keep-alive缓存也是基于vnode节点而不是直接存储dom节点。 它将满足条件(include与exclude)的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点从cache对象中取出并渲染。

29.vue2检测数据的变化

  1. 使用 Vue.set API(在组件中,使用 this.$set)进行修改。this.$set(要修改的数组,要修改的索引值,改变后的值)

    change() {
       this.$set(this.list, 0, 改变后的值)
    }
  2. Vue 对数组常见的 7个操作方法进行了重新包装,保证在数组操作前能监听到数组变化。包括以下七种:

  • push:从数组尾部插入
  • pop:从数组尾部移除
  • unshift:从数组头部插入
  • shift:从数组头部移除
  • splice:替换
  • sort:排序
  • reverse:颠倒顺序
// 方法1
change() {
   this.$set(this.list, 0, '改变后的值')
}

// 方法2
change() {
   // 能监听到 hobby 的变化
   this.list.splice(0, 1, '改变后的值')
}

30.vue组件中的data为什么是函数?

  • 如果data是一个函数的话,这样每复用一次组件,就会返回一份新的data(类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据)
  • Object是引用数据类型,里面保存的是内存地址,单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果。

31. jq中的ready方法 和 js中的onload方法的区别 

  1. 两个方法的执行顺序不一样,jQuery版本不同,方法的执行顺序不同。在jQuery3.0.0版本之前的版本中,$(document).ready会先于window.onload执行,在jQuery3.0.0版本及之后的版本中,window.onload先执行。
  2. 编写个数不同。window.onload不能同时编写多个,如果有多个window.onload方法,只会执行最后一个onload方法。 $(document).ready()可以同时编写多个,并且都可以得到执行。
  3. 简化写法。window.onload没有简化写法 ;$(document).ready(function(){}) ,可以简写成$(function(){});

32.diff算法 

概念:

diff算法就是进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后用patch记录的消息去局部更新Dom。

理解: diff的过程就是调用名为patch的函数,比较新旧节点,一边比较一边给真实的DOM打补丁 。

33.回流和重绘

什么是回流和重绘?

重绘简单来说就是重新绘画,当给一个元素更换颜色、更换背景,虽然不会影响页面布局,但是颜色或背景变了,就会重新渲染页面,这就是重绘。

当增加或删除dom节点,或者给元素修改宽高时,会改变页面布局,那么就会重新构造dom树然后再次进行渲染,这就是回流。

什么时候会发生回流?

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

2、元素的位置发生改变

3、元素的尺寸发生改变

4、内容改变

5、页面第一次渲染的时候

34.css3新增属性有哪些?

border-color:为边框设置多种颜色  

border-image:图片边框 

border-radius:圆角边框 

box-shadow:阴影效果 

background-size:指定背景图片尺寸 

background-origin:指定背景图片从哪里开始显示 

background-clip:指定背景图片从什么位置开始裁剪 

text-shadow:文本阴影 

word-wrap:自动换行  

transform变换效果 

transform-origin 属性可以设置变换的起点 

animation动画效果 

transition过渡效果

35.http和http的区别

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

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

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

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

36.三次握手四次挥手

握手:

1、第一次握手:客户端给服务器发送一个 SYN 报文。

2、第二次握手:服务器收到 SYN 报文之后,会应答一个 SYN+ACK 报文。

3、第三次握手:客户端收到 SYN+ACK 报文之后,会回应一个 ACK 报文。

4、服务器收到 ACK 报文之后,三次握手建立完成。

挥手:

1、第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态。

2、第二次握手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 + 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT状态。

3、第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。

4、第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 + 1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态

5、服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。

37.在浏览器输入一个网址,发生了什么?

1. 浏览器查找该域名的 IP 地址

2.浏览器根据解析得到的IP地址向 web 服务器发送一个 HTTP 请求

3. 服务器收到请求并进行处理

4. 服务器返回一个响应

5. 浏览器对该响应进行解码,渲染显示。

6. 页面显示完成后,浏览器发送异步请求。

7.整个过程结束之后,浏览器关闭TCP连接。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值