前端面试题

说一说cookie sessionStorage localStorage 区别?

共同点:

都是存储在浏览器本地的

区别:

cookie是由服务器端写入的,而SessionStorage、 LocalStorage都是由前端写入的。

cookie的生命周期是由服务器端在写入的时候就设置好的,LocalStorage是写入就一直存在,除非手动清除,SessionStorage是页面关闭的时候就会自动清除。

cookie的存储空间比较小大概4KB,SessionStorage、 LocalStorage存储空间比较大,大概5M。

Cookie、SessionStorage、 LocalStorage数据共享都遵循同源原则,SessionStorage还限制必须是同一个页面。

在前端给后端发送请求的时候会自动携带Cookie中的数据,但是SessionStorage、LocalStorage不会。

应用场景:

Cookie一般用于存储登录验证信息SessionID或者token。

LocalStorage常用于存储不易变动的数据,减轻服务器的压力。

SessionStorage可以用来检测用户是否是刷新进入页面,如音乐播放器恢复播放进度条的功能。

怎么判断this指向?

1. 在全局环境中调用就指向window。

2. 作为对象的方法调用就指向该对象。

3. 作为构造函数调用就指向这个新创建的对象。

4. 可以使用apply,call,bind改变this指向。

5. 箭头函数中的this与定义时所处的上下文绑定,且不能被改变, 箭头函数this指向取决于它外层找到的离它最近的第一个非箭头函数的this。

说一说JS数据类型有哪些,区别是什么?

JS数据类型分为两类:

一类是基本数据类型,也叫简单数据类型,包含7种类型,分别是Number 、String、Boolean、BigInt、Symbol、Null、Undefined。

另一类是引用数据类型也叫复杂数据类型,通常用Object代表,普通对象,数组,正则,日期,Math数学函数都属于Object。

数据分成两大类的本质区别:

基本数据类型和引用数据类型它们在内存中的存储方式不同。

基本数据类型是直接存储在中的简单数据段,占据空间小,属于被频繁使用的数据。

引用数据类型是存储在内存中,占据空间大。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,当解释器寻找引用值时,会检索其在栈中的地址,取得地址后从堆中获得实体。

Symbol 创建数据具有唯一性,所以 Symbol() !== Symbol(), 同时不可枚举,需使用getOwnPropertySymbols获取。

BigInt 也是ES6新出的一种数据类型,这种数据类型的特点就是数据涵盖的范围大,能够解决超出普通数据类型范围报错的问题。

说一说你对闭包的理解?

1.内层函数引用外层函数中变量,这些变量的集合就是闭包

2.通过作用域链,当前作用域可以访问上级作用域中的变量 (原理)

3.解决的问题:保存变量

4.带来的问题:内存泄露

5.闭包的应用:防抖节流、块级作用域

说一说promise是什么与使用方法?

1. 概念:异步编程的一种解决方案,解决了地狱回调的问题

2. promise存在三种状态pending(起始状态),fulfilled(结束状态),rejected(结束状态),

3. 使用方法:new Promise((resolve,reject) => { resolve(); reject(); }) 里面有多个resovle或者reject只执行第一个。如果第一个是resolve的话后面可以接.then查看成功消息。如果第一个是reject的话,.catch查看错误消息。

4. Promise是宏任务(同步执行),只有Promise的回调是异步微任务

5. Promise的缺陷:状态一经改变无法逆转、内部无捕捉错误能力(借助try/catch)、无法监听内部执行状态。

说一说跨域是什么?如何解决跨域问题?

跨域:当前页面中的某个接口请求的地址和当前页面的地址如果协议、域名、端口其中有一项不同,就说该接口跨域了。
跨域限制的原因:浏览器为了保证网页的安全,出的同源协议策略。

跨域解决方案:

前端:

1.利用script标签中的src属性发送jsonp请求,将回调函数作为参数拼接在url中,但是这种方式只支持get请求无法解决其他的请求类型。

2.前端配置一个代理服务器(proxy)代替浏览器去发送请求:因为服务器与服务器之间是可以通信的不受同源策略的影响。

服务端:

1.服务端通过配置cors来解决跨域,配置响应头:setHeader(access-control-allow-origin,对应的域名)

说说BFC

定义:

块级格式化上下文,独立渲染区域,不会影响外界的元素

什么情况下可以让元素产生BFC:
1、float属性不为none
2、position为absolute或fixed
3、display为inline-block、table-cell、table-caption、flex、inline-flex
4、overflow不为visible

BFC元素具有的特性:
1、在BFC中,盒子从顶部开始垂直地一个接一个排列
2、盒子垂直方向的距离由margin决定。同一个BFC的两个相邻盒子margin会重叠
3、BFC中,margin-left会触碰到border-left(对于从左至右的方式,反之)
4、BFC区域不会与浮动的盒子产生交集,而是紧贴边缘浮动
5、计算BFC高度时,自然会检测浮动的盒子高度

主要用途:
1、清除内部浮动,父元素设置为BFC可以清除子元素的浮动(最常用overflow:hidden,IE6需加上*zoom:1):计算BFC高度时会检测浮动子盒子高度
2、解决外边距合并问题
3、右侧盒子自适应:BFC区域不会与浮动盒子产生交集,而是紧贴浮动边缘

 盒模型介绍

CSS3 中的盒模型有以下两种:标准盒模型IE(替代)盒模型

两种盒子模型都是由 content + padding + border + margin 构成,其大小都是由 content + padding + border 决定的,但是盒子内容宽/高度(即 width/height)的计算范围根据盒模型的不同会有所不同:

  • 标准盒模型:只包含 content
  • IE(替代)盒模型:content + padding + border

可以通过 box-sizing 来改变元素的盒模型:

  • box-sizing: content-box :标准盒模型(默认值)。
  • box-sizing: border-box :IE(替代)盒模型。

说一说JavaScript有几种方法判断变量的类型?

1. typeof(根据二进制判断),不能判断数据类型:null和object

2. intanceof(根据原型链判断),原生数据类型不能判断

3. constructor(用于引用数据类型),不能判断null数据类型,对于引用数据类型除了function返回’function‘,其余全部返回’object'。

4. Object.prototype.toString.call()(用Object的toString方法判断)所有类型数据都能判断,记住判断结果打印为:'[object Xxx]'

说一说样式优先级的规则是什么?

!important > 行内样式(style) > ID选择器 > 类选择器(class)、伪类、属性 > 标签选择器、伪元素> 通配符

说一说JS实现异步的方法?

异步微任务:回调函数,promise,async/await

异步宏任务:setTimeout,setIntervial

数组去重都有哪些方法?

new Set():

let array = [...new Set(arr)]

indexOf:

if(array.indexOf(arr[i]) == -1){ array.push(arr[i])}

filter:

array.filter((item, index, self) => {return self.indexOf(item) === index})

双重for循环

如何解决浮动的塌陷

1.给父级添加高度

2.给父级添加 overflow:hidden

3.创建一个空白div,添加 clear:both 属性

4.添加一个after伪元素:

::after{

        content:" ";

        width:0;

        height:0;

        display:block;

        clear:both;

}

rgba()和 opacity 的透明效果有什么不同 

1. rgba()和 opacity 都能实现透明效果,但最大的不同是 opacity 作用于元素,以及元素内的
所有内容的透明度,
2. 而 rgba()只作用于元素的颜色或其背景色。(设置 rgba 透明的元素的子元素不会继承透明
效果!)

es6的箭头函数

1. 没有自己的this,即不能作为构造函数,里面的this是执行上下文的this

2. 不能被new

3. 没有arguments对象

4. 不能作为generator函数,不能用yied命令

5. 没有prototype属性

call apply bind的作用和区别?

1、fn.call (newThis,params) call函数的第一个参数是this的新指向,后面依次传入函数fn要用到的参数。会立即执行fn函数。

2、fn.apply (newThis,paramsArr) apply函数的第一个参数是this的新指向,第二个参数是fn要用到的参数数组,会立即执行fn函数。

3、fn.bind (newThis,params) bind函数的第一个参数是this的新指向,后面依次传入函数fn要用到的参数。  不会立即执行fn函数,且只能改变一次fn函数的指向,后续再用bind更改无效。

CSS尺寸设置的单位

1. px:绝对像素

2. rem:相对于根元素像素

3. em:相对于父元素像素

4. vw:视口宽度

5. vh:视口高度

未知宽高元素水平垂直居中方法

1. 设置元素相对父级定位`position:absolute;left:50%;right:50%`,让自身平移自身高度50% `transform: translate(-50%,-50%);`,这种方式兼容性好,被广泛使用的一种方式
2. 设置元素的父级为弹性盒子`display:flex`,设置父级和盒子内部子元素水平垂直都居中`justify-content:center; align-items:center` ,这种方式代码简洁,但是兼容性ie 11以上支持,由于目前ie版本都已经很高,很多网站现在也使用这种方式实现水平垂直居中
3. 设置元素的父级为网格元素`display: grid`,设置父级和盒子内部子元素水平垂直都居中`justify-content:center; align-items:center` ,这种方式代码简介,但是兼容性ie 10以上支持
4. 设置元素的父级为表格元素`display: table-cell`,其内部元素水平垂直都居中`text-align: center;vertical-align: middle;` ,设置子元素为行内块`display: inline-block; `,这种方式兼容性较好

5. 使用定位position:absolute; top,bottom,left,right:0;

JS变量提升

var声明的变量存在变量提升、let与const声明的变量不存在提升,但是存在暂时性死区的问题。

变量提升:在js编译阶段将该被声明的变量提升至代码的最前面。同时声明优先级来说,函数提升优先级大于变量提升。

暂时性死区:暂时性死区是在变量未定义之前,就访问该变量所造成的的问题

HashRouter 和 HistoryRouter的区别和原理

区别:

1. history和hash都是利用浏览器的两种特性实现前端路由,history是利用浏览历史记录栈的API实现,hash是监听location对象hash值变化事件来实现

2. history的url没有'#'号,hash反之

3. 相同的url,history会触发添加到浏览器历史记录栈中,hash不会触发,history需要后端配合,如果后端不配合刷新新页面会出现404,hash不需要。

HashRouter的原理:通过`window.onhashchange`方法获取新URL中hash值,再做进一步处理

HistoryRouter的原理:通过`history.pushState `使用它做页面跳转不会触发页面刷新,使用`window.onpopstate` 监听浏览器的前进和后退,再做其他处理

hash模式下url会带有#,需要url更优雅时,可以使用history模式。 需要兼容低版本的浏览器时,建议使用hash模式。 需要添加任意类型数据到记录时,可以使用history模式。

map 和 forEach 的区别?

相同点:

1.都能遍历数组

2.函数中都有三个参数(当前遍历的元素,当前元素的索引,原数组)

3.map和forEach用只能用 try...catch...中断抛出错误中断,而return不能,用其效果相当于for循环的continue会跳过此次循环进入下一次循环。

不同点:

1.map有返回值,创建新数组,而forEach无返回值,返回结果undefined

2.map的效率比forEach高

3.map不能修改原数组,forEach能改变原数组

事件循环Event loop,宏任务与微任务

事件循环:js是单线程的,主线程在执行时会不断循环往复的从同步队列中读取任务,执行任务,当同步队列执行完毕后再从异步队列中依次执行

宏任务与微任务都属于异步任务。

宏任务:任务队列中的任务称为宏任务,每个宏任务中都包含了一个微任务队列。

微任务:等宏任务中的主要功能都完成后,渲染引擎不急着去执行下一个宏任务,而是执行当前宏任务中的微任务

宏任务包含:定时器,Dom事件,ajax事件

微任务包含:promise的回调、MutationObserver 的回调 ,process.nextTick

浏览器垃圾回收机制

1. 标记清除:对所有活动对象进行标记,清除阶段会将没有标记的对象清除;

2. 标记整理算法:标记结束后,算法将活动对象压入内存一端,则需要清理的对象在边界,直接被清理掉就行。(效率低)

3. 引用计数:将对象是否不再需要简化定义为有没有其他对象引用它,如果没有引用指向这个对象,则会被垃圾回收机制回收。(内存空间不连续)

CSRF攻击是什么?

1. 概念:跨域请求伪造。

2. 原理:诱导用户跳转到新的页面,利用 服务器的验证漏洞 和 用户之前的登入状态,来模拟用户进行操作。

3. 预防CSRF攻击:添加验证码、使用token验证。

XSS攻击是什么?

XSS指跨站脚本攻击,是攻击者通过向被攻击网站注入恶意代码实现攻击,当被攻击者登录这些网站是就会执行恶意代码,读取cookie、session cookie以及其他敏感信息,对用户进行钓鱼欺诈,甚至发起蠕虫攻击等

浏览器如何渲染页面的

1、HTML被HTML解析器解析成DOM树。

2、CSS被CSS解析器解析成CSS规则树。

3、浏览器会将CSS规则树附着在DOM树上,并结合两者生成渲染树Render Tree。

4、生成布局(flow),浏览器通过解析计算出每一个渲染树节点的位置和大小,在屏幕上画出渲染树的所有节点。

5、将布局绘制(paint)在屏幕上,显示出整个页面

new会发生什么

1. 创建一个新的空对象

2. 将新对象的__proto__(原型)指向构造函数的prototype(原型对象)

3. 构造函数绑定新对象的this并执行返回结果

4. 判断返回结果是否为null,如果为null,返回新对象,否则直接返回执行结果。

token 能放在cookie中吗?

可以

1. 客户端使用用户名跟密码请求登录

2. 服务端收到请求,去验证用户名与密码

3. 验证成功后,服务端签发一个 token ,并把它发送给客户端

4. 客户端接收 token 以后会把它存储起来,比如放在 cookie 里或者 localStorage 里

5. 客户端每次发送请求时都需要带着服务端签发的 token(把 token 放到 HTTP 的 Header 里)

6. 服务端收到请求后,需要验证请求里带有的 token ,如验证成功则返回对应的数据

浏览器输入URL发生了什么?

1、URL解析:判断浏览器输入的是搜索内容还是URL;

2、查找缓存:如果能找到缓存则直接返回页面,如果没有缓存则需要发送网络请求页面;

3、DNS域名解析;

4、三次握手建立TCP连接;

5、发起HTTP请求;

6、服务器响应并返回结果;

7、通过四次握手释放TCP连接;

8、浏览器渲染;

9、js引擎解析;

伪数组和数组的区别

伪数组的特点:类型是object、不能使用数组方法、可以获取长度、可以使用for in遍历

伪数组可以装换为数组的方法:

a. Array.prototype.slice.call(伪数组)

b.Array.from()

c. [...伪数组]

有哪些是伪数组:函数的参数arguments,Map和Set的keys()、values()和entires()

创建ajax过程

1.创建`XMLHttpRequest`对象,创建一个异步调用对象.

var ajax= new XMLHttpRequest();

2.连接服务器

ajax.open(“GET 请求方式”,‘getDate 地址’,async是否开启异步(默认true开启));

3.发送请求

ajax.send()

4.XMLHttpRequest取得响应,处理请求事件

ajax.onreadystatechange = function(){

    if(ajax.readyState === 4 & ajax.status === 200){

    }

}

ajax的状态码

0: 请求未初始化
1: 已发送请求
2: 已接收请求
3: 请求处理中
4: 请求完成并且已响应

回流、重绘

回流:

当一个元素的位置、尺寸等发生改变的时候 浏览器需要重新计算该元素的几何属性并且摆放到正确的位置的过程就叫做回流。

一般像页面初次渲染、带有动画的元素、添加/删除功能、图片放大缩小、浏览器窗口发生改变的时候都会触发回流。

重绘:

当一个元素的外观、样式发生改变而布局不会改变,重新绘制的过程叫做重绘。

回流必定会触发重绘,而重绘则不一定会触发回流。

前端性能优化手段

一、文件加载更快:

1、减小资源大小:文件和图片的压缩;

2、减少请求次数:合并和雪碧图、精灵图,节流防抖;

3、减少渲染次数/重绘回流:缓存:http缓存、本地缓存和vue的keep-alive缓存。

二、文件渲染更快:

1、提前渲染:ssr服务端渲染;

2、优化资源加载:CSS放在html的head中,js放在body底部,处理页面布局的文件放在head中,body中尽量不写style和script标签;

3、懒加载;

4、减少渲染次数/重回回流:DOM缓存、减少dom数量等

服务端渲染

SSR是指从服务端侧完成页面DOM结构和数据的拼接,然后再发送给浏览器,为其绑定事件和状态,能完成交互的过程。

优点:

1. 减少前端耗时,解决首屏加载慢问题;

2. 有利于SEO,提高搜索效率;

3. 无需占用客户端资源;

4. 后端生成静态文件;

缺点:

1. 不利于前后端分离,开发效率不高;

2. 占用服务器的资源。实现方式:传统的JSP、express+react、express+ejs、vue+nuxt。

使用场景:

一般不会用在公司项目内(涉及前后端分离开发问题),可以用户博客网站、官网、营销类网站等比较注重加载速度和渲染效率的时候。

扩展运算符(...)、浅拷贝、深拷贝

对象中的扩展运算符(...)用于取出参数对象中的所有可遍历的属性,浅拷贝到当前的对象中。

浅拷贝:

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

深拷贝:

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

常见的git操作

git branch 查看本地所有分支
git status 查看当前状态
git commit 提交
git branch -a 查看所有的分支
git branch -r 查看远程所有分支
git commit -am "init" 提交并且加注释
git remote add origin git@192.168.1.119:ndshow
git push origin master 将文件给推到服务器上
git remote show origin 显示远程库origin里的资源
git push origin master:develop
git push origin master:hb-dev 将本地库与服务器上的库进行关联
git checkout --track origin/dev 切换到远程dev分支
git branch -D master develop 删除本地库develop
git checkout -b dev 建立一个新的本地分支dev
git merge origin/dev 将分支dev与当前分支进行合并
git checkout dev 切换到本地dev分支
git remote show 查看远程库
git add .
git rm 文件名(包括路径) 从git中删除指定文件
git clone git://github.com/schacon/grit.git 从服务器上将代码给拉下来
git config --list 看所有用户
git ls-files 看已经被提交的
git rm [file name] 删除一个文件
git commit -a 提交当前repos的所有的改变
git add [file name] 添加一个文件到git index
git commit -v 当你用-v参数的时候可以看commit的差异
git commit -m "This is the message describing the commit" 添加commit信息
git commit -a -a是代表add,把所有的change加到git index里然后再commit
git commit -a -v 一般提交命令
git log 看你commit的日志
git diff 查看尚未暂存的更新
git rm a.a 移除文件(从暂存区和工作区中删除)
git rm --cached a.a 移除文件(只从暂存区中删除)
git commit -m "remove" 移除文件(从Git中删除)
git rm -f a.a 强行移除修改后文件(从暂存区和工作区中删除)
git diff --cached 或 $ git diff --staged 查看尚未提交的更新
git stash push 将文件给push到一个临时空间中
git stash pop 将文件从临时空间pop下来

 常见的HTTP状态码

    <!-- 1xx:指示消息,表示请求已接收,继续处理 -->

    <!-- 2xx:成功,表示请求已被成功接收,处理 -->
    <!-- 
         200 OK:客户端请求成功
         204 No Content:无内容。服务器成功处理,但未返回内容。一般用在只是客户端向服务器发送信息,而服务器不用向客户端返回什么信息的情况。不会刷新页面。
         206 Partial Content:服务器已经完成了部分GET请求(客户端进行了范围请求)。响应报文中包含Content-Range指定范围的实体内容
     -->

    <!-- 3xx 重定向 -->
    <!-- 
         301 Moved Permanently:永久重定向,表示请求的资源已经永久的搬到了其他位置。
         302 Found:临时重定向,表示请求的资源临时搬到了其他位置
         303 See Other:临时重定向,应使用GET定向获取请求资源。303功能与302一样,区别只是303明确客户端应该使用GET访问
         307 Temporary Redirect:临时重定向,和302有着相同含义。POST不会变成GET
         304 Not Modified:表示客户端发送附带条件的请求(GET方法请求报文中的IF…)时,条件不满足。返回304时,不包含任何响应主体。虽然304被划分在3XX,但和重定向一毛钱关系都没有
     -->

    <!-- 4xx:客户端错误 -->
    <!-- 
         400 Bad Request:客户端请求有语法错误,服务器无法理解。
         401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
         403 Forbidden:服务器收到请求,但是拒绝提供服务
         404 Not Found:请求资源不存在。比如,输入了错误的url
         415 Unsupported media type:不支持的媒体类型
     -->

    <!-- 5xx:服务器端错误,服务器未能实现合法的请求。 -->
    <!-- 
         500 Internal Server Error:服务器发生不可预期的错误。
         503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,
     -->

 HTTP和HTTPS协议的区别

1、HTTPS协议需要CA证书,费用较高;而HTTP协议不需要
2、HTTP协议是超文本传输协议,信息是明文传输的,HTTPS则是具有安全性的SSL加密传输协议;
3、使用不同的连接方式,端口也不同,HTTP协议端口是80,HTTPS协议端口是443;
4、HTTP协议连接很简单,是无状态的;HTTPS协议是具有SSL和HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP更加安全

SPA单页面有什么优缺点

优点:

1.良好的交互体验
单页应用的内容的改变不需要重新加载整个页面,获取数据也是通过Ajax异步获取,没有页面之间的切换,就不会出现“白屏现象”,也不会出现假死并有“闪烁”现象,页面显示流畅,web应用更具响应性和更令人着迷。

2.良好的前后端工作分离模式
后端不再负责模板渲染、输出页面工作,后端API通用化,即同一套后端程序代码,不用修改就可以用于Web界面、手机、平板等多种客户端。

3.减轻服务器压力
单页应用相对服务器压力小,服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍。

缺点:

1.首屏加载过慢;

解决方案:
a. Vue-router懒加载

b. 使用CDN加速

c. 异步加载组件

d. 服务端渲染
 

2.SEO 不利于搜索引擎抓取

解决方案:

a. 服务端渲染
服务器合成完整的 html 文件再输出到浏览器

b. 页面预渲染
路由采用h5 history模式

哪些情况会导致内存泄漏

1、意外的全局变量:由于使用未声明的变量,而意外的创建了一个全局变量,而使这个变量一直留在内存中无法被回收
2、被遗忘的计时器或回调函数
3、脱离 DOM 的引用:获取一个 DOM 元素的引用,而后面这个元素被删除,由于一直保留了对这个元素的引用,所以它也无法被回收。
4、闭包:不合理的使用闭包,从而导致某些变量一直被留在内存当中。

面向对象以及原型

面向对象:将需求抽象成一个对象,然后对其成员进行分析


面向对象三大特征:封装、继承、多态


面向对象的第一步是创建构造函数,第二步通过构造函数创建对象实例


原型:对象的属性和方法,有可能是定义在自身,也有可能是定义在它的原型对象,由于原型本身也是对象,又有自己的原型,所以形成了一条原型链。


函数的原型是 prototype
对象的原型是 __proto__
对象的顶级原型为null, 即Object.prototype.__proto__ == null

get与post两种方式的优缺点

get:
1、get是从服务器上获取数据,post是向服务器传送数据;
2、get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB;
3、get安全性非常低,post安全性较高。但是执行效率却比Post方法好;
4、get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到;
5. 在做数据查询时,建议用Get方式;

post:
1、post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址,用户看不到这个过程;
2、所以:包含机密信息的话,建议用Post数据提交方式;而在做数据添加、修改或删除时,建议用Post方式。

js数组方法

concat():合并数组,并返回合并之后的数据  

join():使用分隔符,将数组转为字符串并返回  

pop():删除最后一位,并返回删除的数据    


shift():删除第一位,并返回删除的数据    


unshift():在第一位新增一或多个数据,返回长度    


push():在最后一位新增一或多个数据,返回长度    


reverse():反转数组,返回结果    


slice():截取指定位置的数组,并返回    


sort():排序(字符规则),返回结果    


splice():删除指定位置,并替换,返回删除的数据    


toString():直接转为字符串,并返回    


valueOf():返回数组对象的原始值    


indexOf():查询并返回数据的索引        


lastIndexOf():反向查询并返回数据的索引

js的几种遍历循环方式

forEach():参数为回调函数,会遍历数组所有的项,回调函数接受三个参数,分别为value,index,self;forEach没有返回值
map():同forEach,同时回调函数返回数据,组成新数组由map返回   
every():同forEach,同时回调函数返回布尔值,全部为true,由every返回true    
some():同forEach,同时回调函数返回布尔值,只要由一个为true,由some返回true

less和sass的区别

Less和Sass的主要不同就是他们的实现方式。
Less是基于JavaScript,是在客户端处理的。
Sass是基于Ruby的,是在服务器端处理的。
关于变量在Less和Sass中的唯一区别就是Less用@,Sass用$。

js中的offset、scroll和client的区别

offsetTop,offsetLeft:获取离最近父容器的位置,如果没有父容器,那么获取离body最近的位置


offsetWidth,offsetHeight:获取元素的大小,包括padding,border,内容。


clientTop,clientLeft: 获取边框的高度和宽度


clientWidth,clientHeight:获取元素的大小,只包括padding和内容


scrollTop,scrollLeft:内容滚出去的距离


screllWidth,screllHeight:不包括滚动条元素的“大小”(隐藏也算)

line-height 的继承

父元素的 line-height 写了具体数值,例如 20px,则子元素 line-height 继承该值。

父元素的 line-height 写了比例,例如 1.5 或 2,则子元素 line-height 也是继承该比例。

父元素的 line-height 写了百分比,例如 300%,则子元素 line-height 继承的是父元素 font-size * 300% 计算出来的值。

----------------------------------  Vue  ----------------------------------

说说什么是 MVVM

1 这 MVVM 是 Model-View-ViewModel 的缩写。MVVM 是一种设计思想。Model 层代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻辑;View 代表 UI 组件,它负责将数据模型转化成 UI 展现出来,View 是一个同步 View 和 Model 的对象

2 在 MVVM 架构下,View 和 Model 之间并没有直接的联系,而是通过 ViewModel 进行交互,Model 和 ViewModel 之间的交互是双向的, 因此 View 数据的变化会同步到 Model 中,而Model 数据的变化也会立即反应到 View 上。

3 对 ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而 View 和 Model 之间的
同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作
DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

 mvvm 和 mvc 区别?它和其它框架(jquery)的区别是什么?

1.这 mvc 和 mvvm 其实区别并不大。都是一种设计思想。主要就是 mvc 中 Controller 演变成mvvm 中的 ViewModel。mvvm 主要解决了 mvc 中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
2. 区别:vue 数据驱动,通过数据来显示视图层而不是节点操作。
3. 场景:数据操作比较多的场景,更加便捷

说一说Vuex是什么,每个属性是干嘛的?

Vuex是什么:

是vue的一个资源管理仓库,存在在vuex的数据可以在实现任意组件间的通信。

Vuex属性:

state 属性用来存储公共管理的数据。

mutations 属性定义改变state中数据的方法。注意:不要在mutation中的方法中写异步方法ajax,那样数据就不可跟踪了 。

getters 属性可以认为是定义 store 的计算属性。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

actions 属性类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。

module 属性是将store分割成模块。

说一说Vue2.0 双向绑定的原理与缺陷?

Vue响应式指的是:

组件的data发生变化,立刻触发试图的更新

实现原理:

Vue 采用数据劫持结合发布者-订阅者模式的方式来实现数据的响应式,通过Object.defineProperty来劫持数据的setter,getter,在数据变动时发布消息给订阅者,订阅者收到消息后进行相应的处理。

缺陷:

只能够监听初始化实例中的data数据,动态添加值不能响应,要使用对应的Vue.set()。

Vue3.0 实现数据双向绑定的方法

在Vue2.0的基础上将Object.definedproperty换成了功能更强大的proxy,原理相同。在vue实例初始化的时候(vm._init()执行的时候)调用Observe类的实例方法observe,传入数据(若是对象则发生递归),将其中每个数据进行一遍数据劫持(get实现依赖收集,set实现事件派发(这里的模式为发布订阅模式))。

补充:相对vue2.0解决的问题:解决无法监听新增属性或删除属性的响应式问题、解决无法监听数组长度和index变化问题。

vue 的 keep-alive

1、keep-alive是vue的内置组件,能在组件切换过程中将状态保留在内存中,相当于缓存,防止DOM的重复渲染;

2、keep-alive有三个属性:include(只有名字匹配的才会被缓存)、exclude(只有匹配的组件才不会被缓存)、max(最多可以缓存多少个组件)。

3、在路由router的中:相应组件下规定meta属性,定义keep-alive:true;

4、可以结合Vue组件实例加载顺序讲解,VNode->实例化->_updata->真实Node,在实例化的时候会判断该组件是否被keep-alive保存过,是的话则直接拿其中的DOM进行渲染。

computed和watch的区别

computed:

计算属性依赖于多个值,具有缓存,只有在当前依赖的值发生改变之后,才会重新计算,不支持异步操作。应用于需要进行大量数值计算的场景

watch:

起到监听的作用,监听一个数据,然后可以进行操作,数值发生变化立即进行后续操作,无缓存,支持异步操作。应用于需要不断监听数值变化、异步或者开销较大而进行操作的场景 watch之中监听需要传入两个参数(普通数据类型),引用数据类型(需要设置deep属性与handle属性的回调函数)

Vue 中 $nextTick 作用与原理

$nextTick的作用:

该方法中的代码会在当前渲染完成后执行,就解决了异步渲染获取不到更新后DOM的问题了。

$nextTick的原理:

1. 把回调函数放入callbacks等待执行

2. 将执行函数放到微任务或者宏任务中

3. 事件循环到了微任务或者宏任务,执行函数依次执行callbacks中的回调

应用场景:

在钩子函数created()里面想要获取操作Dom,把操作DOM的方法放在$nextTick中

v-if 和 v-show

相同点:都是控制元素隐藏和显示的指令

区别:

v-show: 控制的元素无论是true还是false,都被渲染出来了,通过display:none控制元素隐藏 ;

v-if: 控制的元素是true,进行渲染,如果是false不渲染,根本在dom树结构中不显示

应用:

v-show: 适合使用在切换频繁显示/隐藏的元素上

v-if: 适合使用在切换不频繁,且元素内容很多,渲染一次性能消耗很大的元素上

Vue 列表为什么加 key

1、key实际上是给vnode的唯一标识,也是diff的一种优化策略,可以根据key更快更准确的找到对应的vnode节点;

2、如果不用key就会使用就地复用原则,下一个元素使用上一个在当前位置元素的状态;

3、如果使用key,vue会更根据key的顺序记录element,曾经拥有了key的element如果不再出现的话,会被直接remove或者destoryed;

4、在v-for的数据list里面删除一个item,item之后的元素index会发生变化。

vue-router 实现懒加载的方法

ES6的impot方式:

component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')

VUE中的异步组件:

component: resolve=>(require(['../views/About'],resolve))

vue钩子函数

1.三个阶段

挂载阶段:beforeCreate、created、beforeMounted、mounted

更新阶段:beforeUpdate、updated

销毁阶段:beforeDestroy、destroyed

2. 每个阶段的特性

beforeCreate:创建实例之前

created:实例创建完成(执行new Vue(options)),可访问data、computed、watch、methods上的方法和数据,可进行数据请求,未挂载到DOM结构上,不能获取el属性,如果要进行dom操作,那就要用nextTick函数

beforeMount:在挂载开始之前被调用,beforeMount之前,会找到对应的template,并编译成render函数

mounted:实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,可进行数据请求

beforeupdate:响应式数据更新时调用,发生在虚拟DOM打补丁之前,适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器

updated:虚拟 DOM 重新渲染和打补丁之后调用,组件DOM已经更新

beforeDestroy:实例销毁之前调用,this仍能获取到实例,常用于销毁定时器、解绑全局事件、销毁插件对象等操作

destroyed: 实例销毁之后

3. 父子组件执行顺序

挂载:父created -> 子created -> 子mounted> 父mounted

更新:父beforeUpdate -> 子beforeUpdated -> 子updated -> 父updated

销毁:父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed

简述每个周期具体适合哪些场景

beforeCreate:在new一个vue实例后,只有一些默认的生命周期钩子和默认事件,其他的东西都还没创建。在beforeCreate生命周期执行的时候,data和methods中的数据都还没有初始化。不能在这个阶段使用data中的数据和methods中的方法


create:data 和 methods都已经被初始化好了,如果要调用 methods 中的方法,或者操作data 中的数据,最早可以在这个阶段中操作


beforeMount:执行到这个钩子的时候,在内存中已经编译好了模板了,但是还没有挂载到页面中,此时,页面还是旧的


mounted:执行到这个钩子的时候,就表示Vue实例已经初始化完成了。此时组件脱离了创建阶段,进入到了运行阶段。 如果我们想要通过插件操作页面上的DOM节点,最早可以在和这个阶段中进行


beforeUpdate: 当执行这个钩子时,页面中的显示的数据还是旧的,data中的数据是更新后的, 页面还没有和最新的数据保持同步


updated:页面显示的数据和data中的数据已经保持同步了,都是最新的


beforeDestory:Vue实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁


destroyed: 这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于不可用状态。组件已经被销毁了。

 Vue的性能优化有哪些

1、数据层级不要过深,合理的设置响应式数据

2、为 for 循环设置唯一的 key 值,可以快速精准的定位到改变的元素,提升 diff 算法的速度

3、v-show(频繁切换性能高)和v-if的合理使用

4、合理使用路由懒加载、异步组件。

5、使用keep-alive来缓存组件

6、数据持久化的问题,使用防抖、节流进行优化,尽可能的少执行和不执行。

7、data中的所有数据都会被劫持,所以将数据尽可能扁平化,如果数据只是用来渲染可以使用Object.freeze,可以将数据冻结起来,这样就不会增加getter和setter。

8、打包优化

vue 常用的修饰符

v-model 修饰符:
.lazy:输入框改变,这个数据就会改变,这个修饰符会在光标离开 input 框才会更新数据
.number:输入字符串转为数字
.trim:输入框过滤首尾的空格

事件修饰符:
.stop:阻止事件冒泡,相当于调用了 event.stopPropagation()方法


.prevent:阻止默认行为,相当于调用了event.preventDefault()方法,比如表单的提交、a标签的跳转就是默认事件

.once:事件只能用一次,无论点击几次,执行一次之后都不会再执行


.capture:事件的完整机制是捕获-目标-冒泡,事件触发是目标往外冒泡


.sync:对 prop 进行双向绑定


.keyCode:监听按键的指令,具体可以查看 vue 的键码对应表

.self:只有元素本身触发时才触发方法,就是只有点击元素本身才会触发。比如一个 div里面有个按钮,div 和按钮都有事件,我们点击按钮,div 绑定的方法也会触发,如果div 的click 加上 self,只有点击到 div 的时候才会触发,变相的算是阻止冒泡

(待更新)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值