前端面试题复习

1. 浏览器解析

  1. 用户输入网址
  2. 对输入的URL进行语法解析,如果网址不合法会抛出错误
  3. 查看本地cache,网址被分段解析后,浏览器首先在本地缓存查询cache,如果cache被标明是最新的则直接使用缓存内容。
  4. dns解析,向dns服务或服务器查询域名所对应的IP地址
  5. 请求连接,tcp三次握手,连接服务器
  6. 发送http请求,向服务器发送请求
  7. 接收服务器响应,服务器发回一个HTML响应,浏览器开始显示HTML,浏览器发送获取嵌入在HTML中的对象
  8. 断开连接
  9. 写cache,将可以缓存的数据写入cache中
  10. 大概:用户输入网址——浏览器查找IP地址——发送HTTP请求——服务器处理请求并响应——服务器发回HTML响应——浏览器开始解析HTML——浏览器发送请求获取HTML中内嵌的对象,如CSS/JS/图片等资源——浏览器展示完整页面
浏览器解析html响应过程
  1. 加载-解析-渲染(加载过程进行解析渲染)
  2. 浏览器自上而下加载html代码,发现link引用外部css文件时,请求css文件,等待服务器响应(异步,不阻塞DOM加载和解析,但会阻塞页面渲染),服务器响应,浏览器解析,浏览器拿到css文件,可以开始渲染页面;发现img时,请求(异步),遇到js外部文件加载(同步),阻塞页面后续的内容的加载以及解析
  3. 解析页面标签生成DOM树,解析css资源生成CCSOM树,Javascript 脚本文件加载后, 通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree
  4. 浏览器引擎通过 DOM Tree 和 CSS Rule Tree 构建 Rendering Tree(渲染树),下一步layout,就是计算出每个节点在屏幕中的位置。 之后绘制rendering tree
  5. 总结一个版本:
  • 浏览器开始解析HTML代码(自上向下),发现link引用外部css文件,请求css文件,服务器响应,浏览器解析;
  • 浏览器继续载入html中<body>部分的代码,并且CSS文件已经拿到手了,可以开始渲染页面了
  • 当发现img标签时,发出请求,此时浏览器不会等待图片加载,而是继续渲染后面的代码;
  • 服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码;
  • 发现script-js脚本,载入后立马执行(不管HTML有没有被渲染),执行后会阻塞页面后续的内容包括页面的渲染、其它资源的下载)。原因:因为浏览器需要一个稳定的DOM树结构,而JS中很有可能有
    代码直接改变了DOM树结构,比如使用 document.write 或
    appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修
    改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现。所以,js 死循环执行不完的话,页面也就别想呈现了,所以,建议将所有的script标签放到页面底部
  • 假设js脚本中有style.display=”none”,执行后,浏览器需要重新渲染部分代码
  • 直至解析至
  • 假若,浏览器点击某些功能改变样式,换了css外部样式,浏览器需要重新向服务器请求新的css文件,重新渲染页面

2. vue的生命周期

vue的生命周期是指从vue实例创建、运行、销毁的过程(开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载)
生命周期函数:

  • 创建期间:
  • beforeCreate():实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的dom,一般不做操作
  • created():挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取(要操作data中的数据和methods中的方法最早只能在created中
  • beforeMount():表示模板已经在内存中编辑完成,但尚未把模板内容渲染到页面中,在beforeMount执行的时候,页面中的元素还没有被真正的替换过来,只是之前写的一些模板字符串。在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数
  • mounted():表示内存中的模板已经真实的挂载到了页面中,用户可以看到渲染的页面,mounted是实例创建期间的最后一个生命周期函数,当执行完mounted,就表示实例已经被完全创建好了,此时,如果没有其他操作的话,这个实例就静静的躺在我们的内存中
  • 运行期间:
  • beforeUpdate():页面还没有被更新,此时data中的数据是最新的,但是界面上显示的还是旧数据,因为此时还没有重新渲染DOM节点
  • updated():数据已经更改完成,执行时页面和data中的数据已经保持同步
  • 销毁期间:
  • beforeDestroy():当经过某种途径调用$destroy方法后,立即执行beforeDestroy,此时vue实例就已经从运行阶段进入销毁阶段,但是实例上的data、methods、以及过滤器,指令等都处于可用状态,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等
  • destroyed():当执行时,组件已经完全销毁了,此时,组件中的所有数据、方法等都不可用了

3. 数组、字符串的常用方法

  • 数组的常用方法 :
  1. toString():数组转为字符串(以逗号分隔)
  2. join():数组转为字符串,可以定义分隔符
  3. push():在数组末尾添加一个或多个元素,返回数组长度
  4. pop():在数组末尾删除最后一个元素,返回移除项
  5. shift():删除数组第一个元素,返回移除向项
  6. unshift():像数组首部添加一个或多个元素,返回新的长度
  7. splice():实现数组的删除、插入、替换,返回删除元素组成的数组
    splice(index,length,item):表示从index开始,删除长度length个元素,插入item
  8. concat():合并数组,原数组不变
  9. slice():裁剪数组,原数组不变
    slice(start,[end]):如果有end下标,返回值不含结束位置
  10. sort():数组排序,默认从小到大
    sort(function(a,b){ return a-b) } 从小到大
    sort(function(a,b){ return b-a) } 从大到小
  11. reverse():反转数组
  12. forEach():遍历数组,没有返回值,元素组不变
    forEach(function(item, index, a){} :a是数组本身
  13. map():对每个数组元素执行函数来创建新数组,不会对没有值的数组元素执行函数,不会更改原始数组
  14. some():检查某些数组值是否通过了测试,只要有一项满足条件,就会返回true
  15. filter():过滤,创建一个包含通过测试的数组元素的新数组,不改变原数组
  16. every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true
  17. find():返回通过测试函数的第一个数组元素的值
  • 字符串的常用方法:
  1. search():搜索特定值的字符串,并返回匹配的位置,可以用正则表达式
  2. slice():提取字符串,
    slice(start, end):不包含结束位置
  3. substring():提取字符串
    substring(start, end):不包含结束位置(无法接受负索引)
  4. substr():提取字符串
    substr(start,length):第二个参数是要提取的长度
  5. replace():替换字符串,默认地,replace() 只替换首个匹配;replace() 对大小写敏感;可以用正则表达式
  6. toUpperCase() | toLowerCase()
    字符串大写|字符串小写
  7. concat():拼接字符串
  8. trim():删除字符串两端的空白符,IE8及其以下不支持
  9. charAt(index):返回字符串中指定下标(位置)的字符串
  10. charCodeAt(index):返回字符串中指定索引的字符 unicode 编码
  11. split():字符串转为数组
	var str6 = "a,b,c,d,e";
    console.log(str6.split(","));//["a", "b", "c", "d", "e"]以逗号分割
    console.log(str6.split(" "));//["a,b,c,d,e"]数组长度为1  以空格分隔
    console.log(str6.split("|"));//["a,b,c,d,e"]  以|分隔
    console.log(str6.split(",",2));// ["a", "b"]  以逗号分隔,返回数量为2
    var str7="Hello World!";
    console.log(str7.split(" "));//["Hello", "World!"] 以空格分隔
    console.log(str7.split(""));//["H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d", "!"]单个字符
  • match():可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。

4. cookie、sessionStorage、localStorage、session的区别

cookie、sessionStorage、localStorage的区别
  • cookie:Web站点跟踪用户技术,指某些网站为了辨别用户身份,进行session跟踪而存储在用户本地终端上的数据
  • sessionStorage:将数据保存在session对象中。所谓session,是指用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。session对象可以用来保存在这段时间内所要求保存的任何数据。这些数据只有在同一会话中的页面才能访问,当用户关闭浏览器窗口后,数据会被删除
  • localStorage:将数据保存在客户端本地的硬件设备中,即使浏览器被关闭了,该数据任然存在,下次打开浏览器访问网站时任然可以继续使用
  • 区别
    共同点:都是保存在浏览器端的,且同源的
    不同:
  • cookie数据会在客户端和服务器之间来回传递,、sessionStorage和localStorae不会自动把数据发送给服务器,仅在本地存储
  • cookie数据不能超过4K,、sessionStorage和localStorae虽然也有存储大小限制,但比cookie大得多,可以达到5M或更大
  • cookie需要指定作用域,不可以跨域调用(在同源窗口都是共享的),sessionStorage不在不同的浏览器窗口中共湘,即使是同一页面;localStorae在所有同源窗口中都是共享的
  • sessionStorage仅仅在当前浏览器窗口关闭之前有效;localStorae始终有效,窗口或浏览器关闭之后也一直保存;cookie只在设置cookie过期时间之前有效。
cookie和session的区别

cookie和session都是用来跟踪浏览器用户身份的会话方式。

  • cookie数据存放在客户的浏览器上,session数据放在服务器上。
  • cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
  • session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
  • 单个cookie保存的数据不能超过4K,很多浏览器都限制nei一个站点最多保存20个cookie。
  • 所以建议:将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中
  • session保存在服务器,客户端不知道其中的信息;cookie保存在客户端,服务器能够知道其中的信息。
  • session中保存的是对象,cookie中保存的是字符串。
  • session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到。而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的。

5. 盒子模型

盒子模型分为W3C标准模型和IE模型

  • W3C标准模型(content-box):盒子的宽为:内容宽度+内边距宽度+边框+外边距宽度
  • IE盒模型(border-box):盒子宽度为:内容宽度(content+padding+border)+外边距宽度
  • 通过box-sizing设置

6. 原型和原型链

原型:

  • 原型是Javascript中的继承的基础,JavaScript的继承就是基于原型的继承。
  • 实例对象中__proto__属性,它是原型,也是一个对象,可以叫做原型对象
  • 构造函数中有个prototype属性,它是原型,也是一个对象,可以叫做原型对象
  • 实例对象的__proto__与构造函数的prototype相等
  • 实例对象的__proto__指向了构造函数的原型对象prototype

原型链:

  • 实例对象、构造函数和原型对象之间的关系
  • 构造函数的prototype指向他的原型对象
  • 实例对象的__proto__指向构造函数的原型对象prototype
  • 原型对象中的constructor指向他的构造函数

7. 数组去重

var arr=[1,4,6,2,1,4,a,a];
function deleteItem(arr){
	for(var i=0;i<arr.length;i++){
		if(arr.indexOf(arr[i])!=i){
			arr.splice(i,1);
			i--;
		}
	}
	console.log(arr);
}
deleteItem(arr);			

方法二:高性能,利用对象属性不会重复特性

function distinct(a, b) {
    let arr = a.concat(b)
    let result = []
    let obj = {}

    for (let i of arr) {
        if (!obj[i]) {
            result.push(i)
            obj[i] = 1
        }
    }

    return result
}

方法三:双重循环
方法四:先排序,判断相邻的两项是否相等
方法五:for…of实现循环

8. CSS选择器

id选择器,class选择器,标签选择器,通配符选择器,属性选择器,子代选择器,后代选择器,相邻选择器,伪类选择器

  • 可继承属性:字体设置的都可以继承,color,font-size等等
  • 不可继承属性:border、padding、margin、width等等
  • 优先级:!important>style行内样式>id选择器>类选择器>标签选择器
css优先级

标签选择器:1
class选择器:10
id选择器:100
style行内样式:1000

9. 清除浮动

浮动:一个盒子使用了CSS float浮动属性,导致父级对象盒子不能被撑开。浮动的本质是实现文字环绕的
浮动的特性

  1. 块级元素可以横排显示
  2. 行内元素可以设置宽度和高度
  3. 元素没有设置宽高时,宽度是撑开的宽
  4. 支持margin,不支持margin:auto
  5. 脱离文档流

清除浮动

  1. 给父元素增加overflow:hidden
    “overflow:hidden”会触发BFC,BFC反过来决定了"height:auto"是如何计算的,即计算BFC的高度时,浮动元素也参与计算,因此此时父元素会自适应浮动元素的高度。所以呢,也可以设置"display:inline-block"、“position:absolute”、"float:left"来解决父元素高度坍塌的问题。因为凡是能创建一个BFC,就能达到包裹浮动子元素的效果。因此网上都说成“BFC能包裹浮动元素”.
.over-flow{
    overflow: auto; 
    zoom: 1; //处理兼容性问题
}
  • 使用伪元素:after:before
    可以给父元素的内容添加一个伪元素,可以用:before或者:after,然后内容为空,这样就不会占据位置,最后为伪元素加上“clear:both"来清除浮动。兼容问题:增加*zoom:1
  • 在父级元素内的末尾加一个块级元素,添加clear:both
  • 父级添加高度

10. JS作用域、闭包

  • 作用域:
    作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。
    js中的作用域分为全局作用域和局部作用域
  • 作用域链:
    作用域有上下级的关系,会在当前作用域中寻找变量,如果找不到会沿着创建时作用域链一直往上找,直到找到全局作用域
  • 闭包:
    在一个函数内部定义的另一个函数,当内部函数在包裹他的函数之外被执行时,就会形成闭包。同时内部函数仍然可以访问到包裹函数中的局部变量与函数。(闭包就是能够读取其他函数内部变量的函数)
    闭包注意点:
    内存消耗大、不能滥用,造成性能问题,在IE中可能造成内存泄漏,解决:手动释放变量

11. ajax中get、post的区别

get和post都是向服务器发送请求,只是发送机制不一样

  • get请求会将参数跟在url后面进行传递,而post会将参数作为http请求得请求正文发送给服务器
  • 发送的数据数量:get请求只能发送的数据最多4K,因为数据是在URL中发送的;post可以发送大量的数据,因为数据是在正文主件中发送的(在http中”GET方式提交的数据最多只能是1024字节”,Post传输的数据量大,可以达到2M。 )
  • 安全性:get发送的数据不受保护,他是分开的,增加了漏洞和黑客攻击的风险;post发送的数据是安全的,它可以使用多种编码技术,这使其具有弹性
  • get请求需注意缓存问题,post请求不需担心这个问题(get方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这些数据,例如账号和密码等。某种情况下,get方式会带来严重的安全问题。而post方式相对来说就可以避免这些问题 )
  • get主要是为了获取数据,post是更新或提交数据

12.jQuery的节点操作

  • 查找结点
  • 创建节点
    $(html)
  • 插入节点
    append
    appendTo
    prepend
    prependTo
    after
    insertAfter
    before
    insertBefore
  • 删除节点
    remove $("li").remove(".current");----$("li:eq(2)").remove();
    empty:清空节点,能清空元素中的所有的文本和后代节点
  • 复制节点
    clone
  • 属性操作
    attr:获取节点属性,设置节点样式
    removeAttr:删除属性
  • 样式操作
    css
    class:addClass、removeClass、toggleClass、hasClass

13. js中的同步异步

同步:需要排队等待,上一个任务完成之后才可以执行
异步:不需要等待

JS是一门单线程语言,所谓单线程就是需要排队等待,前一个任务结束之后,才可以执行本任务

  • JS为什么是单线程的?
    避免复杂性
    js最初的目的是实现和用户的交互以及DOM操作,假若他不是单线程,它会带来复杂的问题,例如:他有两个线程,一个在某个节点上添加了内容,一个删除了这个节点,那么浏览器应该以哪个线程为主?
  • JS中为什么要加异步?
    如果JS中不存在异步,只能自上而下执行,万一上一行解析时间很长,那么下面的代码就会被阻塞。导致了很差的用户体验

14. var、let、const的区别

  • var声明的变量会挂载在window上,let和const不会
  • var声明的变量存在变量提升,let和const不存在
  • let和const声明形成块作用域
  • 同一作用域下的let、const不可以声明同名变量,var可以
  • 暂存死区
    报错:在当前块作用域中,用let或const声明的变量,给a赋值10的时候,只会在当前作用域下查找,此时还没有声明,所以会报错a is not defined
var a = 100;
if(1){
    a = 10;
    let a = 1;
}
  • const一旦申明必须赋值,不能用null占位,声明之后不可以修改,若声明的是复杂类型变量,可以修改

15. 跨域

跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景。
所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
1、 通过jsonp跨域 (缺点:只能实现get一种请求)
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域

16. flex布局

给予容器控制内部元素高度和宽度的能力
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content

17. 事件委托

事件本来是加在某些元素上的,然而却加到别人身上来做,完成这个事件。利用冒泡的原理,把事件加到父级上,触发执行效果
好处:
提高性能
新添加的元素也有事件
作用:
支持为同一个DOM元素注册多个同类型事件
可将事件分成事件捕获和事件冒泡机制

18. 继承

  1. 原型链继承
    Per.prototype=new Person()
    缺点:无法实现多继承
  2. 借用构造函数实现继承
    借用call、apply实现继承
    特点:复制父类的实例属性给子类,可以实现多继承
    缺点:不能继承原型上的属性和方法
  3. 组合继承
    原型链继承+构造函数继承
  4. 拷贝继承
  5. 原型式继承
  6. 构造函数+深拷贝
  7. 寄生组合继承
    通过寄生方式,砍掉父类的实例属性,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性

19. Promise

  • Promise是一个构造函数,也是一个对象,可以通过new来创建一个实例,他保存着未来将要结束的事件
  • 在promise上有两个函数:resolve()、reject()
  • Promise表示一个异步操作,每当new一个实例时,实例就表示一个具体的异步操作,结果只有两种:成功、失败,只能使用回调函数将结果返回给调用者
  • 在Promise构造函数prototype中有.then方法,可以在new出来的实例上使用.then方法,预先为这个Promise异步操作指定成功和失败的回调函数
  • 只要一创建就会立即执行:每当创建一个实例时,就会立即执行这个异步操作中的代码
  • 将Promise的异步操作定义为一个方法,就可以按需执行
  • Promise有三种状态:pending进行中、fulfilled已成功、rejected已失败,任何其他操作都不能改变这个状态,这也是Promise的名字的由来
  • .catch捕获异常

20. 前端优化

1、网络方面

  • 减少HTTP请求
    • 合并js文件
    • 合并css文件
    • 使用base64编码表示简单的图片
    • 精灵图的使用css sprite
  • 减少资源体积
    • gzip压缩
    • js混淆
    • 图片压缩
    • css压缩
  • 缓存
    • DNS缓存
    • CDN部署与缓存
    • http缓存
  • 移动端优化
    • 使用长cache,减少重定向
    • 首屏优化,保证首屏加载数据小于14kb
    • 不滥用web字体

2、渲染和DOM操作方面

  • 优化网页渲染
    • css放在头部,js放在底部或者异步
  • DOM操作优化
    • 避免在document上直接进行频繁的DOM操作
    • 使用classname代替大量的内联样式修改
    • 对于复杂的UI元素,设置position为absolute或fixed
    • 尽量使用css动画
    • 使用requestAnimationFrame代替setInterval操作
    • 适当使用canvas
    • 尽量减少css表达式的使用
    • 使用事件代理
      3、数据方面
  • 图片加载处理
    • 图片预加载
    • 图片懒加载
    • 首屏加载进度条显示

21. ES6

22. bootstrap的优点

23. H5、C3新增

H5:email、data、number、range、audio、video、header、footer、nav、aside、artical
C3:box-shadow、border-image、text-shadow、word-wrap

24. 打勾动画

25. HTTP、HTTPS

http是超文本传输协议,依靠TCP完成的可靠

你可能感兴趣的:(前端笔面复习)