2021年前端面试题总结

1.git 命令

$ git init  //在目录中创建新的Git仓库
$ git status  //查看仓库状态
$ git add    //提交到暂存区
$ git commit -m '备注' // 暂存到本地仓库
$ git push -u origin master //推送到git仓库
$ git push // 第二次推送的时候就可以直接推送了
$ git pull // 获取远程仓库的更新
$ git branch 分支名字  //创建分支
$ git checkout 分支名字 // 切换分支
$ git checkout -b 分支名字// 创建并且切换分支
// 合并分支 推送到git hub  、
首先,切换到分支,敲 git log 命令,查找需要合并的commit记录,比如commitID:7fcb3defff;
然后,切换到master分支,使用 git cherry-pick 7fcb3defff  命令,就把该条commit记录合并到了master分支,这只是在本地合并到了master分支;
最后,git push 提交到master远程,至此,就把develop分支的这条commit所涉及的更改合并到了master分支。

2.redux和vuex的区别

vuex是吸收了Redux的经验并且对redux的进行了调整,从而对仓库的管理更加明确,vuex还放弃了一些特性做了一些优化,代价是只能和vue配合

vuex有自动渲染的功能,所以不需要更新

Redux 是一个状态管理系统

3.跨域问题

出现跨域问题的原因:

在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问问题。在请求的过程中我们要想回去数据一般都是post/get请求,所以…跨域问题出现

跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号(如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。

什么是同源策略:

跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号(如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。

同源策略 是由NetScape提出的一个著名的安全策略。所谓的同源,指的是协议,域名,端口相同。浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。

受同源策略(SOP)的影响,协议+域名+端口

  1. 通过jsonp跨域(只支持get请求)

原理是通过标签script的src属性中的链接可以访问跨域的脚本,使用jq提供jsonp

Js跨域请求数据是不可以的,但是js跨域请求js脚本是可以的。所以可以把要请求的数据封装成一个js语句,做一个方法的调用。跨域请求js脚本可以得到此脚本。得到js脚本之后会立即执行。可以把数据做为参数传递到方法中。就可以获得数据。从而解决跨域问题。jsonp原理:(动态创建script标签,回调函数)浏览器在js请求中,是允许通过script标签的src跨域请求,可以在请求的结果中添加回调方法名,在请求页面中定义方法,就可获取到跨域请求的数据。为什么不是真正的 ajax?    1、ajax和jsonp这两种技术在调用方式上"看起来"很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。3、所以说,其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。4、还有就是,jsonp是一种方式或者说非强制协议,如同ajax一样,它也不一定非要json格式来传递数据,如果你愿意,字符换也行,只不过这样不利于jsonp提供公开服务。
  1. 跨域资源共享(CORS)

2.在服务器Response Header,响应头中的Access Control Allow Origin为对应的域名,后台更改header

3.用http-proxy-middleware(配置代理服务器的中间件)

4. 前端优化问题

  1. 减少http请求的次数,精灵图 本地缓存 函数防抖节流

  2. 图片懒加载

  3. 少用全局变量、缓存DOM节点查找的结果

  4. 少操作Dom,可以一次性运行完,然后再操作Dom节点

  5. 优化CSS(压缩合并css,如 margin-top, margin-left…)

  6. 网址后加斜杠(如www.campr.com/目录,会判断这个目录是什么文件类型,或者是目录。) cdn托管

    你如何对网站的文件和资源进行优化?

    1、文件合并(目的是减少http请求)

    2、文件压缩(目的是直接减少文件下载的体积)

    3、使用cdn托管资源

    4、使用缓存

    5、gizp压缩你的js和css文件

    6、meta标签优化(title,description,keywords)、heading标签的优化、alt优化
    7、反向链接,网站外链接优化

5. vuex

应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态

state:驱动应用的数据源

view:以声明方式将state映射到视图

action:响应在view上的用户输入导致的状态变化

Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作

Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。

State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。

使用场景:组件之间的状态,登录状态

Vuex流程 :

在vue组件里面,通过dispatch来触发actions提交修改数据的操作,然后通过actions的commit触发mutations来修改数据,mutations接收到commit的请求,就会自动通过mutate来修改state,最后由store触发每一个调用它的组件的更新

6. vue生命周期

创建前后 beforeCreated created

载入前后 beforeMount mounted

更新前后 beforeUpdate update

销毁前后 beforeDestroy destroyed

说说你对vue的理解:Vue是一套构建用户界面的渐进式的自底向上增量开发的MVVM框架,核心是关注视图层,vue的核心是为了解决数据的绑定问题,为了开发大型单页面应用和组件化,所以vue的核心思想是数据驱动和组件化,这里也说一下MVVM思想,MVVM思想是 模型  视图  vm是v和m连接的桥梁,当模型层数据修改时,VM层会检测到,并通知视图层进行相应修改.Vue循环的key作用:Key值的存在保证了唯一性,Vue在执行时,会对节点进行检查,如果没有key值,那么vue检查到这里有dom节点,就会对内容清空并赋新值,如果有key值存在,那么会对新老节点进行对比,比较两者key是否相同,进行调换位置或删除操作

7.ajax

是一种无需重新加载整个网页的情况下,能够更新部分网页的技术

  • 原生ajax:

1)创建Ajax引擎对象

2)为Ajax引擎对象绑定监听(监听服务器已将数据响应给引擎)

3)绑定提交地址

4)发送请求

5)接受响应数据

编写JS实现JS原生ajax功能function fn1() {//发送异步请求//1.创建ajax引擎对象----所有操作都是由ajax引擎完成var xmlHttp = new XMLHttpRequest();//2.为引擎对象绑定监听事件xmlHttp.onreadystatechange = function() {//当状态变化时处理的事情if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {//5.接收响应信息var data = xmlHttp.responseText;//alert(data);document.getElementById("span1").innerHTML=data;}}//3.绑定服务器地址//第一个参数:请求方式GET/POST//第二个参数:后台服务器地址//第三个参数:是否是异步 true--异步   false--同步xmlHttp.open("GET", "${pageContext.request.contextPath}/ajaxServlet?username=zhangsan",true);            //4.发送请求xmlHttp.send();}_________________________________________________________________________________________
// 新建一个XMLHttpRequest对象
var xhr = new XMLHttpRequest();// 设置请求。 xhr.open(请求的方式,get|post, 请求的url地址);
xhr.open('get', '/common/getCurrentTime');// 设置回调函数。返回的数据存放在xhr.responseText中。
xhr.onload = function() {// 注:xhr.responseType属性,设置返回类型。(例如:设置了json格式,从xhr.response中取得返回数据)console.info('从服务器返回的数据', xhr.responseText);
};
// 发送请求。
xhr.send();

7.1 get和post的区别

  • get

    • 参数拼接在url(url?name=1&age=30),在xhr.open()第二个参数中处理
    • 由于浏览器对url长度的支持(各个浏览器均不同)是有限制,所以,它只能附加少量的数据。
  • post
    • 要设置请求头: xhr.setRequestHeader(‘content-type’,‘application/json’)
    • 参数写在send()方法中:send(‘对象字符串’)
    • 相对于get 来说,没有传参大小的限制。

url:代表请求的服务器端地址

data:代表请求服务器端的数据(可以是key=value形式也可以是json格式)

callback:表示服务器端成功响应所触发的函数(只有正常成功返回才执行)

type:表示服务器端返回的数据类型(jquery会根据指定的类型自动类型转换)

常用的返回类型:text、json、html等。

8. 模板引擎 模板字符串

模板字符串 :ES6中新增了模板字符串,允许使用一对反引号来定义字符串,字符串允许换行。并且字符串中连接变量可以使用${}

例子:

var str = `hello`;
var html = `<li><a href="#">啦啦啦</a></li>
`;----------------------------------
var obj = {name: '张三'};
var arr = ['jack', 'tom'];
var x = 123;
var a = 'lalal', b = 'hahaha';var str = `我的名字是${obj.name},我的朋友是${arr[0]},我今年${x}岁了`;
var str = `字符串中可以拼接${a + b}`;

性能优化,尽量少操作Dom,我们可以一次性遍历完后台数据,拼成长的模板,然后一次性加到页面中(通过Dom.append(),这是jquery里面的方法)

例子:

var lis=''; //首先定义一个空串,遍历的时候往里面加字符串
res.forEach((item,index,arr)=>{lis=`${lis}<li>${item.name}</li>`  // 这里面的${lis}就是相当于拼接字符串,把上次拼接的结果,跟这次的拼接结果,放到一块
})
$('dom元素').append(lis)  //最后一次性加到dom元素内

模板引擎 :数据量比较小的时候用模板字符串,数据量大的时候用模板引擎

步骤:

  1. 首先引入模板引擎,script标签的src属性引入地址链接

  2. 将我们要渲染的模板单独放到一个script标签里面

  3. 我们要给模板加一个id,这样才能找到模板

  4. 调用template函数(引入的函数),template函数的三个参数:

    函数的参数1:模板的id

    函数的参数2: 需要展示的数据(必须写成对象的数据 例如{key:value})(后端所有的数据,我们在单独的script标签中对它进行遍历)

    函数的返回值str:即拼接到一起的一个html 字符串(相当于之前用模板字符串拼接的lis)

{{each key v}}  key就是我们要遍历的数据,v就是遍历数据的每一项
</each>
<script type='text/html' id='moban'>
//  这里面放入我们要遍历的模板遍历的数据{{v.name}}{{v.age}}
{{/script}}

8.1 append 和 innerHTML 和innerText

  • append 是jQuery里面的方法 可以同时传入多个节点或字符串,没有返回值;据说 append 还是试用期的方法,有兼容问题,(但我用了暂时火狐,谷歌,iE都能使用)。

不会覆盖原对象里面的内容,是在原内容后插入,还有在前面插入的方法prepend

使用方法:

Dom.append('要添加的标签及内容')

再原生js里面也可以用,就是不能转化标签

  • innerHTML 添加的是纯字符串,不能获取内部元素的属性;不同于 appendChild 添加到的是 dom 对象,返回的也是 dom 对象,可以通过 dom 对象访问获取元素的各种属性。

通过它添加内容,会将原元素里面的内容覆盖掉,包括标签元素

使用方法:

Dom.innerHTML=`要添加的标签及内容`
  • innerText 只能赋值纯文本 ,不能赋值标签元素

9.http

http是要基于TCP连接基础上的,简单的说,TCP就是单纯建立连接,不涉及任何我们需要请求的实际数据,简单的传输。http是用来收发数据,即实际应用上来的。

9.1 状态码

HTTP状态码由3位数字构成,其中首尾数字定义了状态码的类型:

1XX: 信息类,表示收到web浏览器请求,正在进一步的处理中

2XX: 成功,表示用户请求被正确接收,理解和处理例如:200 ok

3XX: 重定向,表示请求没有成功,客户必须采取进一步的措施

4XX: 客户端错误,表示客户端提交的请求有错误,例如:404 NOT

5XX: 服务器端出现错误,表示服务器不能完成对请求的处理:例如 500

200 OK 服务器成功处理了请求(这个是我们见到最多的)204 No Content  请求成功处理,没有实体的主体返回206 Partial Content  GET范围请求已成功处理301/302 Moved Permanently(重定向)请求的URL已移走。Response中应该包含一个Location URL, 说明资源现在所处的位置303 See Other  临时重定向,期望使用GET定向获取304 Not Modified  发送的附带条件请求未满足307 Temporary Redirect  临时重定向,POST不会变成GET400 Bad Request  请求报文语法错误或参数错误401 Unauthorized  需要通过HTTP认证,或认证失败403 Forbidden  请求资源被拒绝404 Not Found(页面丢失)未找到资源500 Internal Server Error  服务器故障或Web应用故障501 Internal Server Error服务器遇到一个错误,使其无法对请求提供服务503 Service Unavailable  服务器超负载或停机维护

10.tcp三次握手四次挥手

三次握手为了确认客户端跟服务器都能接受到对方的信息,两次的话服务器不能确认客户端能否接收自己发的包
第一次握手,客户端给服务器发包。 此时服务器确认自己可以接收客户端的包,客户端不确认服务器是否接收到了自己发的包
第二次握手,服务器端回复客户端。 此时客户端确认自己发的包被服务器收到,也确认自己可以正常接收服务器包,客户端对此次通信没有疑问了。服务器可以确认自己能接收到客户端的包,但不能确认客户端能否接收自己发的包
第三次握手,客户端回复服务器。 客户端已经没有疑问了,服务器也确认刚刚客户端收到了自己的包。两边都没有问题,开始通信

四次挥手

(1)首先客户端想要释放连接,向服务器端发送一段TCP报文

(2)服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段TCP报文

(3)服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文

(4)客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务器端发送一段报文

https://baijiahao.baidu.com/s?id=1654225744653405133&wfr=spider&for=pc

11. cookie和session的区别

Cookies:cookie在浏览器与服务器之间来回传递,cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭,cookie数据不能超过4k。

session:Session是存放在服务器的内存中里,所以session里的数据不断增加会造成服务器的负担,所以会把很重要的信息存储在session中,session的信息是通过sessionid获取的,而sessionid是存放在会话cookie当中的,当浏览器关闭的时候会话cookie消失,所以sessionid也就消失了,但是session的信息还存在服务器端。一般session是和cookie结合起来使用的

js可以操作cookie

// 函数中的参数分别为 cookie 的名称、值以及过期天数
function setCookie(c_name,value,expiredays){var exdate=new Date();exdate.setDate(exdate.getDate()+expiredays);document.cookie=c_name+ "=" +escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString())
}
setCookie('name','zzyn',1); // cookie过期时间为1天。// 如果要设置过期时间以秒为单位
function setCookie(c_name,value,expireseconds){var exdate=new Date();exdate.setTime(exdate.getTime()+expireseconds * 1000);document.cookie=c_name+ "=" +escape(value)+((expireseconds==null) ? "" : ";expires="+exdate.toGMTString())
}
setCookie('name','zzyn',3600);  //cookie过期时间为一个小时

12. git 与svn的区别

git是分布式管理:支持离线操作

svn是集中式管理 :只能联网才能正常工作

13.大数字的处理方式

大数字的范围-253~253

可以使用插件json-bigint

JSON.parse()【从一个字符串中解析出json对象】

JSON.stringify()【从一个对象中解析出字符串】

14.localStorage和sessionStorage的区别

共同点:都是保存在浏览器端、且同源的 区别: 1、cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下 2、存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大 3、数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭 4、作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的 5、web Storage支持事件通知机制,可以将数据更新的通知发送给监听者 6、web Storage的api接口使用更方便

15.为什么要使用语义化标签

语义是指对一个词或者句子含义的正确解释。很多html标签也具有语义的意义,也就是说元素本身传达了关于标签所包含内容类型的一些信息。

  • 代码结构: 使页面没有css的情况下,也能够呈现出很好的内容结构
  • 有利于SEO: 爬虫依赖标签来确定关键字的权重,因此可以和搜索引擎建立+ 良好的沟通,帮助爬虫抓取更多的有效信息
  • 提升用户体验: 例如title、alt可以用于解释名称或者解释图片信息,以及label标签的灵活运用。
  • 便于团队开发和维护: 语义化使得代码更具有可读性,让其他开发人员更加理解你的html结构,减少差异化。
  • 方便其他设备解析: 如屏幕阅读器、盲人阅读器、移动设备等,以有意义的方式来渲染网页。

16.css3网页的过渡效果

CSS3中新增的transform属性,可以实现元素在变换过程中的过渡效果,实现了基本的动画。

17.原型链

原型的概念:每一个javascript对象(除null外)创建的时候,就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型中“继承”属性。

这是每个对象(除null外)都会有的属性,叫做proto,这个属性会指向该对象的原型。

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

18.闭包

闭包就是指有权访问另一个函数作用域中的变量的函数。

5.闭包是什么?有什么特性?对页面会有什么影响

闭包可以简单理解成:定义在一个函数内部的函数。其中一个内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

特点:

1.函数嵌套函数。

2.函数内部可以引用外部的参数和变量。

3.参数和变量不会被垃圾回收机制回收。

使用:

1.读取函数内部的变量;

2.这些变量的值始终保持在内存中,不会在外层函数调用后被自动清除。

优点:

1:变量长期驻扎在内存中;

2:避免全局变量的污染;

3:私有成员的存在 ;

缺点:会造成内存泄露

19.let和const

  1. let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
  2. const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。

20.flex布局

就是弹性布局

  • flex内容宽度等分

父盒子display:flex

子盒子:flex:1

  • 左右布局一侧定宽,一侧自适应撑满

父盒子display:flex

子盒子

.left{width:300px}

.right{width:100%}

  • 未知高度,上下左右居中

父盒子

.main{display:flex;justify-content:center;align-item:center
}

子盒子:

.box{width:300px;
}

21.webpack打包命令

// webpack4的命令
node_modules/.bin/webpack app/main.js -o common/index.js

22.echars的CDN使用

要引入两个js文件

一个是echars的js文件

一个就是需要使用的地图图表的js文件

23.map与foreach的区别

  • map方法 有返回值 可以reture出来

  • 语法格式
    arr[].map(function(value,index,array){
    xxx
    return xxx
    });
    示例

    let arr = [1,2,3,4,5]
    let newarr =arr.map(item=>{
    arr.push(10)
    return item*2
    })
    console.log(arr) //[1, 2, 3, 4, 5,10,10,10,10,10]
    console.log(newarr) //[2, 4, 6, 8, 10]

map不改变原数组,他可以返回一个新的数组,当遍历数组时,内部改变原数组的时候,不会改变新的数组,就是说新添加的元素不会进入循环里面。

  • foreach 没有返回值
  • 语法格式
    arr[].forEach(function(value,index,array){
    xxxxx
    })
    示例
    let arr = [1,2,3,4,5]
    let newarr =arr.foreach(
    (item,index,input)=>{
    input[index]=item*10
    })
    console.log(newarr) //undifind
    console.log(arr) //[1,2,3,4,5,10,10,10,10,10]
    理论上这个方式是没有返回值的,只是遍历数组中的每一项,不对原来数组进行修改,但是可以自己通过数组的索引来修改原来的数组

24.TCP与UDP的区别

UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议,当报文发送之后,是无法得知其是否安全完整到达的。首先 UDP 是不需要和 TCP一样在发送数据前进行三次握手建立连接的,想发数据就可以开始发送了。并且也只是数据报文的搬运工,不会对数据报文进行任何拆分和拼接操作。

TCP协议全称是传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议,三次握手,四次挥手

https://www.cnblogs.com/fundebug/p/differences-of-tcp-and-udp.html

25.promise如何解决回调地狱

首先ajax 还有setTimeout都是异步

promise实例有resolve以及reject、all方法

原型上有then catch方法

function getContent(file){return new Promise(function(resolve,reject){fs.readFile(file,'utf8',function(err,data){if(err){return reject('文件读取错误:'+err)}})})}// 这时候我们在调用封装的promise
getContent('1文件的url').then(function(data){      //文件1读取出来的结果console.log(data) return getContent('2文件的url') //返回一个实体的Promise对象 这样下面的then方法才能调用}).then(function(data){    //读取到文件2的结果console.log(data) return getContent('3文件的url') //返回一个实体的Promise对象 这样下面的then方法才能调用}).then(function(data){   //读取到文件3的结果console.log(data) }).catch(function(err){conso.log(err) // 可以捕捉到错误} )
  • .then方法会返回一个空的promise对象,因此我们可以在后续连续使用.then()的方法
  • 如果then内部有return返回一个实体的promise对象,那么其会被返回出来

26.如何优化界面上传图片的界面

27.封装axios请求

其实都可以统称为请求配置

  • 默认配置:配置axios的默认项 如基本地址baseURL
  • 请求配置 :请求拦截器(一般在请求头配置请求头) 响应拦截器
  • transformResponse这是在响应拦截器之前发挥作用,一般用来处理大数字

28.原生放大镜

28.1 animate函数封装

原生轮播图 思想:排他思想

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>轮播图</title><style>#loopDiv{width: 790px;height: 340px;margin: 0 auto;position: relative;}#list{list-style: none;position: absolute;bottom: 10px;left: 250px;}#list li{float: left;width: 20px;height: 20px;line-height: 20px;text-align: center;border-radius: 50%;background: #aaa;margin-right: 10px;}.chooseBut{width: 50px;height: 80px;background-color: rgba(0,0,0,0.2);color: #fff;font-size: 30px;line-height: 80px;text-align: center;display: none;}#left{position: absolute;left: 0px;top: 130px;}#right{position: absolute;right: 0px;top: 130px;}</style>
</head>
<body><div id="loopDiv">![](img/0.jpg)<ul id="list"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li></ul><div id="left" class="chooseBut"><</div><div id="right" class="chooseBut">></div></div><script type="text/javascript">var jsDivBox = document.getElementById("loopDiv");//图片节点var jsImg = document.getElementById("pic");//左右按钮节点var jsLeft = document.getElementById("left");var jsRight = document.getElementById("right");//获取所有的livar jsUl = document.getElementById("list");var jsLis = jsUl.getElementsByTagName("li");//让第一个小圆点变为红色jsLis[0].style.backgroundColor = "red";//显示当前的图片下标var currentPage = 0;//启动定时器var timer = setInterval(func, 1000);function func() {currentPage++;changePic();}function changePic() {if (currentPage == 8) {currentPage = 0;}if (currentPage == -1) {currentPage = 7;}//更换图片//"img/1.jpg"jsImg.src = "img/" + currentPage + ".jpg";//将所有的小圆点颜色清空for (var i = 0; i < jsLis.length; i++) {jsLis[i].style.backgroundColor = "#aaa";}//改变对应小圆点为红色jsLis[currentPage].style.backgroundColor = "red";}//鼠标进入jsDivBox.addEventListener("mouseover", func1, false);function func1() {//停止定时器clearInterval(timer);//显示左右按钮jsLeft.style.display = "block";jsRight.style.display = "block";}//鼠标移出jsDivBox.addEventListener("mouseout", func2, false);function func2() {//重启定时器timer = setInterval(func, 1000);//隐藏左右按钮jsLeft.style.display = "none";jsRight.style.display = "none";}//点击左右按钮jsLeft.addEventListener("click", func3, false);function func3() {currentPage--;changePic();}jsLeft.onmouseover = function() {this.style.backgroundColor = "rgba(0,0,0,0.6)";}jsLeft.onmouseout = function() {this.style.backgroundColor = "rgba(0,0,0,0.2)";}jsRight.addEventListener("click", func4, false);function func4() {currentPage++;changePic();}jsRight.onmouseover = function() {this.style.backgroundColor = "rgba(0,0,0,0.6)";}jsRight.onmouseout = function() {this.style.backgroundColor = "rgba(0,0,0,0.2)";}//进入小圆点for (var j = 0; j < jsLis.length; j++) {jsLis[j].onmouseover = function() {currentPage = parseInt(this.innerHTML) - 1;changePic();};}</script>
</body>
</html>

27.将时间戳转换为正常格式(原生)

var time = new Date();获取时间戳var y = time.getFullYear();转化年
var m = time.getMonth()+1;转化月
var d = time.getDate();转化日
var h = time.getHours();转化时
var mm = time.getMinutes();转化分
var s = time.getSeconds();转化秒console.log(y+'-'+m+'-'+d+' '+h+':'+mm+':'+s)

28.mvvm vue数据绑定原理

      // Object.defineProperty() 原生js就自带的方法// vue 也是js 他就是一个封装了 js的 库而已// Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。// vue的原理// Object.defineProperty(对象,属性名,{  get set 等配置 }) // data.name='李四' 设置值 就会触发 set// vue 原理// vue 通过 原生js的 Object.defineProperty 监听到了 我们写的data数据// 这个data里面的数据 有修改 就会触发 Object.defineProperty 里面的 set // 在set里面 我们可以 获取到最新的修改的值 去页面上 正则匹配到对应地方 替换修改// 你看过vue 源码  如果没看过就说 没怎么看过 只是了解了一下 稍微写了一下// 但是 这段时间 建议大家 去百度看看  稍微知道点东西function Vue(){this.data={name:'zs'}// 那 vue的data 那么多数据怎么办?// vue里面 就循环执行下面这段话 不就全部data 监听到了吗?// for()Object.defineProperty(this.data,'name',{get:function(){// 当获取监听对象的某个 值  就可以 执行get函数 console.log('get 获取了值')},set:function(newval){ // 设置的新值console.log('set 设置了值',newval)// 当然vue 没有这么简单去找 他写了很多正则表达式去替换// 但是思路是这个  // 我只需要 监听到 name值改了  就去页面修改 对应的地方就行 变成新值let con=document.getElementById("con")// con.innerHTML  获取内容  name的值是:{{name}}  .replace("查找的字符串","替换成这个")let str=con.innerHTML.replace("{{name}}",newval)// 重新修内容  innerHTML 是获取内容 设置内容的con.innerHTML=str}})}let vm=new Vue()// vm.data  // console.log(data.name) ;// 获取// vue 的核心 如果数据改变了 那么页面就跟着改变成最新数据了// 为什么vue可以知道你的数据更新了?// 因为vue 帮我监听了 set 然后你只要设置值 就触发set 只需要在set里面找到页面对应的数据修改就行document.getElementById("btn").onclick=function(){// data.name='小雷'// console.log(data.name) ;// 这就是获取值vm.data.name='李四'}

29.DOM和BOM

将整个网页抽象成一个对象

将浏览器抽象成一个对象

30. 定时器setInterval setTimeout

  • setInterval( )方法会不停地调用函数,直到clearInterval( )被调用 或者 窗口被关闭
  • setTimeout( )定时器只会执行一次,通过clearTimeout清除定时器

31.页面中插入视频

  • flash:兼容性比较好,视频会压缩,相比其他格式没有那么大,但是要知道的是视频越小质量就会越差的,而且flash方式插入的视频对移动端也不友好。如果要考虑移动端的话最好是用html5.

  • html5:由于每个浏览器支持不同格式的视频,所以你必须在服务器放置好几个不同格式的视频,但是基本上公司都设有自己的服务器,硬盘的容量还是有保证的,毕竟可以还自己买硬盘加上。而在网络上传输的话由于视频的格式相比flash格式视频是大了些,占用带宽也会大,但是它的质量会更好些。

  • 在页面中插入格式为FLA的视频,几乎所有电脑都有安装Flash Player多媒体播放器

1:选择能适用于 Flash Player的输出格式,Adobe Media Encoder CS4中选择 FLV|F4V,格式工厂中选择FLV。

2:打开Dreamweaver点击插入------媒体-------插入FLV,选择你要添加的FLV视频。当把视频文件添加到web页面中时,Dreamweaver在页面中添加一个flash影片控制下载和播放(称为视频播放器)。页面中需要有足够的空间显示视频和视频播放器。

  • Dreamweaver中有两种不同的发布视频的方式(视频类型“选项)

累进式下载视频:首先将FLV文件下载到访问者的硬盘上,当下载了足够多的视频文件后就开始播放,它允许下载完成之前就开始播放视频文件。

优点:

  • 服务器上不需要安装除了web服务器(apache或iis)以外的软件。
  • 只要跟其他WEB资源一样,把视频传到服务器上即可。

缺点:

  • 无法认证用户,不能管理和报告视频被下载的总量,也不能降低单个用户的可用带宽。
  • 视频文件会被web浏览器缓存到用户电脑上,用户可以找到缓存里的视频文件并另存,这样就很难限制视频文件的传播。

流视频:Flash Player链接到服务器,视频以流的形式传播,当收到信息后,会显示出来,然后就从内存中消除,它从不保存到用户磁盘上。

优点:

  • 可以及时回放视频,而不需要等下载一定多的量后才播放。

  • 可以验证用户,只有授予权限的用户才能访问视频。

  • 可以根据用户和视频文件分配带宽。

  • 视频文件不会被浏览器缓存,所以能控制传播。

  • HTML5 DOM 为 音频和 视频 元素提供了方法、属性和事件。

浏览器会根据自己的支持度开选择具体加载那种格式的视频文件,当然服务器端必须对同一个视频提供多种格式的支持

video标签嵌入本地视频的话,直接在video的src中填写视频在项目中的地址即可,目前video标签嵌入视频的话不支持嵌入第三方视频,我试过将iframe的src里的优酷视频链接放到video的标签中,运行的时候无法播放。

第三种:借用插件video.js

所需的文件都在“dist”这个文件里面,video.js插件界面用全部用css制作,所以“font”界面文件,“lang”提示语言(默认用的是英文)

第四种:iframe嵌入—本地视频和支持嵌入第三方视频

 <!-- 使用iframe嵌入本地视频 --><div style="width: 500px;height: 380px;margin: 0px auto;"><iframe width="500px" height="380px" src="mda-ic3eip66u80zeutr.mp4" frameborder=0 allowfullscreen></iframe></div><!-- 使用iframe嵌入第三方视频(例如:优酷视频、腾讯视频、土豆视频) --><div style="width: 500px;height: 380px;margin: 0px auto;"><iframe width="500px" height="380px"            src="http://player.youku.com/embed/XMzcwNTY3NTM2MA" frameborder=0 allowfullscreen>               </iframe></div>

1.1:第一种就是iframe嵌入本地视频的demo,直接在iframe的src中填写视频在项目中的地址并加上allowfullscreen属性即可。(关于allowfullscreen属性的作用,在后面的内容中会解释)

1.2:第二种就是我目前需求所需要的,可以在H5页面中嵌入第三方视频的方法。这里以优酷视频为例,首先在iframe的src中填写优酷视频引用链接,格式如下:

http://player.youku.com/embed/XMzcwNTY3NTM2MA

绿色部分是优酷通用的引用链接(不用修改),红色部分填写你想嵌入视频的ID。(下方有获取优酷视频ID的教程

32.C3和H5新特性

H5的新特性

1.语义化标签

  1. 有利于SEO,有助于爬虫抓取更多的有效信息,爬虫是依赖于标签来确定上下文和各个关键字的权重。
  2. 语义化的HTML在没有CSS的情况下也能呈现较好的内容结构与代码结构
  3. 方便其他设备的解析
  4. 便于团队开发和维护

2.表单新特性

3.多媒体视频(video)和音频(audio)

4.web存储

  1. sessionstorage:关闭浏览器清空数据,储存大小约5M。
  2. localstorage:永久生效,存储大小20M,多窗口下都可以使用
  3. 都只能储存字符串

C3的新特性

1.选择器:属性选择器E[attr],伪类选择器E:nth-child(n),空伪类E:empty ,排除伪类E:not(selector)

2.颜色:新增了RGBA、HSLA模式

3.文本:为文本设置阴影增强文本的表现能力,通过 text-shadow,可分别设置偏移量、模糊度、颜色(可设透明度)。

4.盒模型:box-sizing: border-box;

5.边框:圆角border-radius,阴影box-shadow

6.背景:

  1. 通过 background-size 设置背景图片的尺寸。
  2. 通过 background-origin 可以设置背景图片定位(background-position)的参照原点。
  3. 通过background-clip,可以设置对背景区域进行裁切,即改变背景区域的大小。

7.渐变:线性渐变 linear-gradient,径向渐变radial-gradient

8.字体图标

9.伸缩盒子:调整主轴对齐justify-content,调整侧轴对齐align-items,伸缩分配flex,正序方式排序order

10.2D转换:

  1. translate 设置元素的位置(x/y坐标)
  2. scale 设置元素的缩放比例(x/y两个方向)
  3. rotate 设置元素旋转(正值为顺时针,负值为逆时针)
  4. transform-origin 设置转换元素的原点

11.3D转换:

  1. 透视(perspective)值为1000px~1200px
  2. 将2D元素转换为3D立体(给父元素设置)transform-style: perserve-3d;
  3. 设置元素背面是否可见 backface-visibility: hidden;

12.动画:

  1. 定义关键帧 @keyframes
  2. 通过百分编写帧
  3. 在各帧中分别定义各属性
  4. 通过animation将动画应用于相应元素

33.浮动布局 felx布局(弹性布局) rem布局 流式布局 响应式布局

常见浏览器内核:

Chrome 统称为Chromium内核或Chrome内核,以前是Webkit内核,现在是Blink内核

Firefox Gecko内核,俗称Firefox内核

Safari Webkit内核

Opera 最初是自己的Presto内核,后来是Webkit,现在是Blink内核

IE Trident内核,也是俗称的IE内核

浮动布局:float: left | right

目的:float的目的是让block同行显示(在父级规定的宽度内、不完全脱离文档流)

Flex是Flexible Box的缩写,意为”弹性布局”(伸缩盒子),用来为盒状模型提供最大的灵活性。

flex布局 :display:flex 调节宽度

目的:是让布局更加简单,可以让盒子,自适应的调节宽度,例如圣杯布局 (左右固定 中间随意拉伸)

使用方法:

父盒子设置为display:flex

子盒子flex:1或者百分数

em:子元素相对于父元素的字体大小来说的 父元素font-size:12px 子元素width:10em 就相当于12*10

rem布局: rem的基准是相对于html元素的字体大小 比如所根元素html设置的font-size=12px,非根元素设置width:2rem,则置换成px表示就是24px

媒体查询@media:有三个关键字 mediatype add(media feature)

  1. 第一个是not|only mediatype 媒体类型 常用的有all所有设备 print打印机 screen电脑手机
  2. add|not|only 关键字 连接第一个和第三个的关键词
  3. media feature 媒体特性 必须用小括号包裹 里面写
    1. max-width 页面最大可见区域宽度 小于等于
    2. min-width 页面最小可见区域宽度
    3. width 页面可见区域宽度
      示例:

因此我们可以采用rem+媒体查询来做布局,来适应不同屏幕的设备

<style>@media screen and (max-width:800px){html{font-size:12px     //  页面宽度小于800的时候font-size设置为12px}}@media screen and (max-width:1200px){html{font-size:24px    // 页面宽度大于800px小于1200px的时候font-size设置为24px}}@media screen and (min-width:800px) {background-color:blue}// 范围宽度,页面宽度是800px~960px的时候显示蓝色</style>

引入资源:当样式比较繁多的时候,我们可以针对不同的媒体使用stylesheets(样式表),原理就是直接在link中判断设备的尺寸,然后引用不同的css文件

<style></style>
<link rel='stylesheet',href='style320.css' media='screen and (min-width:320px)'></link>
<link rel='stylesheet',href='style640.css' media='screen and (min-width:640px)'></link>

通过媒体查询进行判断屏幕尺寸,

  1. 当小于640大于320的时候,我们可以通过样示,让他们宽度100%,两行顶满
  2. 当大于640的时候,我们可以通过样式让两个兄弟div,通过浮动,宽度设置为50%,一行显示

rem适配方案1:(划分为15等份)

  1. 页面元素的rem值=页面元素值(px)/(屏幕宽度/划分的分数)
  2. 屏幕宽度/划分的分数 就是html font-size的大小
  3. 因此:页面元素的rem值=页面元素值(px) / html font-size 字体的大小

rem适配方案2:(划分为10等份)

  1. 下载flexible
  2. px转化成rem插件 cssrem 设置 更多操作 搜索cssroot ,复制到右侧,修改默认的font-size,然后就可以修改了,重启就可以了

流式布局:调节宽度:也就是百分比布局,也称为非固定像素布局

通过盒子的宽度设置成百分比,来根据屏幕的宽度进行伸缩,不受固定像素的限制,内容向两边填充

34.盒模型与 box-sizing

盒模型是由 padding border margin content组成

box-sizing:content-box / border-box /inherit

box-sizing :最主要的用法是规定容器元素的最终尺寸计算方式。(默认是conter-box,还有border-box以及inherit(指定box-sizing的值应该从父元素继承)

如果你创造了一个

没有设置 box-sizing 属性为 border-box(不设置的话默认值为 content-box.),同时你设置 width:100px; border:10px solid red; padding:10px; 那么最终 div 容器的实际宽度为:
100px(width)+2*10px*(padding)+2*10px(border)=140px

所以你会得到一个比你预期(100px)还要更大的容器,结果就是会破坏网页布局。

注意:容易 margin 的尺寸不会被计算入最终容器宽度,因为对他的定义为对这个容器的留白,但不属于容器本身。

如果当我们定义一个容器的 box-sizing 属性为 border-box 时(表达式:br{box-sizing:border-box}),那么我们创建一个和上段中相同设置的

容器时,那么他的最终宽度即为 100px, 那么它的内容部分(content)的有效宽度变成了 100px-2 10px-210px =60px; 所以你会得到一个你预期大小的盒子容器,但是只是被压缩了内容部分尺寸而已,但是对于整体布局而言益处颇多。所以要合理利用好这个属性,这个属性十分重要。

35.数组方法

push( ) 向数组的末尾添加一个新元素

unshift( ) 向数组的开头添加一个新元素

pop( ) 删除数组的最后一个元素

shift( ) 删除数组的第一个元素

cancat( ) 合并数组

reverse( ) 将一个数组中的元素的顺序反转排序

slice(1,3) 从一个数组中选择元素 // 获取下标为1,2的元素

join( ) 用数组的元素组成字符串 join可以指定连接字符

var arr=[123,456,789]
undefined
arr.join('')  // "123456789"
arr.toString('')  // "123,456,789"
arr.join()  // "123,456,789"
arr.join('#')  // "123#456#789"

tostring( ) 转换数组到字符串

sort( ) 元素的大小排序 如果里面有参数,那么b就代表数组的第一个元素,a就代表数组的第二个元素

  • 若 a 小于 b,则返回一个小于 0 的值。在排序后的数组中 a 应该出现在 b 之前
  • 若 a 等于 b,则返回 0。
  • 若 a 大于 b,则返回一个大于 0 的值。排序后的数组中 a 应该出现在 b 之后

正序

arr.sort(function(a,b){return a-b});)

倒叙

arr.sort(function(a,b){return b-a});)
  1. 字符串方法

trim( ) 删除字符串两边的空格 IE8不支持

indexOf( ) 来定位字符串中某一个指定的字符首次出现的位置 ,字符串的空格也算是一个位置

match( ) 查找字符串中特定的字符,如果找到就返回这个字符,否则就返回null

toUpperCase( ) 字符串大小写转换,文本转换为大写

toLowerCase( ) 文本转换为小写

split( ) 字符串转换为数组,split(’,’)使用逗号分隔,也可以使用其他符号分隔,这里的分隔符必须是字符串里面的分隔符,才能有效果

slice( ) 裁剪字符串 (开始位置,结束位置],不包含裁剪开始的位置

substr( ) 裁剪字符串(开始位置,裁剪长度),与上面相似但不同

replace( ) 替换字符串(被替换的字符串,替换的字符串),返回一个新的字符串,不改变原先的字符串

charAt( )返回指定索引位置处的字符,如果超出有效范围的索引值返回空字符串

37. 找出一串字符串中重复最多的字符,并将其打印出来

function getmaxObj(str) {if (str.length == 1) {return str;}var newObj = {};// 这个for循环是创建对象newObj里面的键值的,每一个数组都创建了一个键值for (var i = 0; i < str.length; i++) {   if (!newObj[str.charAt(i)])//newObj[字符串]=>newObj['对象内的属性名字']=>newObj.属性名newObj[str.charAt(i)] = 1;elsenewObj[str.charAt(i)] += 1;}console.log(newObj)var maxObj = {maxkey: "",maxvalue: 0}// 从键值中筛选出值最大的一个for (var k in newObj) { if (newObj[k] > maxObj.maxvalue) {maxObj.maxvalue = newObj[k];maxObj.maxkey = k;}}return maxObj;
}
var result = getmaxObj("zhangpeiyue.com");
// 出现最多的字符:e
console.log("出现最多的字符:" + result.maxkey);
// 出现次数:2
console.log("出现次数:" + result.maxvalue);

创建一个对象

var newObj = {};

然后添加我们添加一个键值

newObj['字符串样式的键名']=1
// 就相当于下面这种形式
newObj.键名=1

以上这两种写法是等价的

38.深拷贝 浅拷贝

原生递归的方法

json的方法

jquery的extend方法

39. 变量提升

变量提升:函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部。

JavaScript 只有声明的变量会提升,初始化的不会。(初始化的意思就是变量在定义的时候就被赋值)

40.引用传递 值传递

引用传递:函数调用中传递是对象,数组,一般称为引用传递

值传递: 函数调用中,传递的是一个数值,我们称为值传递

//**值传递**<script>var n =10function fun(n) {// 在函数中开辟了一个空间a==10 相当于var a=5n++;            // 11console.log(n); 11}fun(n);// 结果是函数没有改变全局变量n的值,所以结果依旧是10console.log(n);      // 10// 函数调用中,传递的是一个数值,我们称为‘值传递’// 特点:修改函数中的空间,对外部空间是没有影响的</script>// **引用传递**<script>var a=20 function fun() {// 开辟了函数空间// 函数中没有a的空间// 所以系统会自动向外搜索// 这里对全局的变量进行了修改a++;             console.log(a); // 21}fun();console.log(a);      // 21</script>

41.同源策源

协议+域名+端口

42.超文本传输协议http ,http是什么?有什么特点

就是前端向后端发送请求的协议

三次握手 四次挥手

http叫做超文本传输协议,是互联网应用最广泛的一种网络协议

特点:基于请求-响应的模式 无状态保存 无连接

43.选择器权重

继承 * 0000

元素选择器 0001

类选择器 伪类选择器 0010

ID选择器 0100

行内样式 1000

!important 无穷大

44.嵌套块元素塌陷

当我们对父盒子的子盒子设置margin时候,会导致父盒子出现塌陷问题

解决办法:

  1. 给父盒子设置一个透明的上边框
    border-top:1px solid transparent
  2. 给父元素定义上内边距
    padding:1px
  3. 给父元素添加overflow:hidden

45.css浮动

就是float:left/right/none(默认不浮动)

浮动可以让块元素在一行显示

特点:

  1. 浮动元素会脱离标准流
  2. 浮动元素会一行内显示并且元素顶部对齐
  3. 浮动元素会具有行内块元素特性

缺点:

子元素浮动脱标,父元素未设置高度的话会出现问题,父元素的兄弟元素会顶上来

解决办法:

  • 额外标签法也称为隔墙法 缺点:结构较差

在浮动元素末尾添加一个空标签,例如:

  • 父级添加overflow属性 缺点:无法显示溢出的部分

overflow:hidden/auto/scroll

  • 父级添加after伪元素

: after{ }

  • 父级添加双伪元素

46.精灵图使用

移动背景图片,使用background-position

使用步骤:

  1. 首先用切片工具定位小图片图片位置
  2. 然后css里面写上

47.字体图标使用

  1. 首先通过阿里矢量图把字体图标下载过来
  2. 引入到页面当中,通过@font-face{ 一大串}
  3. 打开demo.html ,里面有我们需要字体图标的编码,打开后就直接复制到我们需要放置的标签中
  4. 我们在标签的css里面写入 font-family:‘icomoon’,还可以通过font-size调节大小,通过color调节颜色

48.前端兼容

移动端适配:

pc端则是同一个浏览器不兼容(ie6 ie7 ie8)跨浏览器不兼容(火狐 谷歌 ie)

49.浏览器的私有前缀

-moz-:代表firefox浏览器私有属性

-ms-:代表ie浏览器私有属性

-webkit-:代表safari、chrome私有属性

-o-:代表=Opera私有属性

提倡写法:

-moz-border-radius:10px

-webkit-border-radius:10px

-o-border-radius:10px

border-radius:10px

50.选择器

属性选择器 :[ title] 带有title属性的全部选择出来 [class=‘demo’]

结构伪类选择器 : nth-child(n) n可以是数字关键字 公式 nth-of-type(n)

伪元素选择器: ::before ::after

51.animation

animation是一个简写属性,用于设置六个动画

animation-name 规定需要绑定到选择器的keyframe名称

animation-duration 规定完成动画所花费的时间,以秒或毫秒计

animation-timing-function 规定动画的速度曲线 默认ease

animation-delay 规定在动画开始之前的延迟 何时开始

animation-iteration-count 规定动画应该播放的次数 默认1次 infinite

animation-direction 规定是否应该轮流反向播放动画 默认normal alternate(反向)

animation-fill-mode 运动完回到的位置,默认是返回起始位置backwards, forwards停留

animation-play-state 规定动画是否正在运行或暂停,默认是‘running’还有‘paused’

简单使用:

  1. 首先我们在@keyframes 动画名称{ 里面写上 0%{ 开始位置} 100%{结束位置}} 0% 100%也可以用from to表示
  2. 调用动画,在我们需要动画的标签css里面写入 animation-name:动画名 animation-duration:动画花费的时间

52.less使用

  • 变量:less可以定义一个变量,然后在其他地方使用即可

    1. 必须有@为前缀
    2. 不能包含特殊字符
    3. 不能以数字开头
    4. 大小写敏感
      @color:yellow;
      body{
      background-color:@color;
      }

我们使用esay less插件,然后再保存less文件,这样就自动生成css文件

  • 嵌套:子元素直接嵌套到父元素内部即可,如果有伪类,我们可以直接在冒号前加一个&
    div{
    .img{
    &:hover{
    color:yellow
    }
    }
    }
  • 运算
    1. 运算符(*)乘号 和(/)除号
    2. 运算符左右空格隔开
    3. 对于两个不同单位的值之间的运算,运算结果的值取第一个值的单位
    4. 如果两个值之间只有一个值有单位,则运算就取该单位
      53.全局安装 本地安装
  • 本地安装 --save-dev --save
    1. 开发依赖 --save-dev 大写的为: -D
    2. 生产依赖 --save 大写的为:-S
  • 全局安装 -g

54.vue路由懒加载 组件懒加载

目的:为给客户更好的客户体验,首屏组件加载速度更快一些,解决白屏问题。

原理:懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载。

未用懒加载的时候router的代码

 import Vue from 'vue'import Router from 'vue-router'import HelloWorld from '@/components/HelloWorld'Vue.use(Router)export default new Router({routes: [{path: '/',component:HelloWorld}]})
  • 常用的懒加载方式有两种:即使用vue异步组件 和 ES中的import

    • vue异步组件,实现懒加载
      import Vue from ‘vue’
      import Router from ‘vue-router’
       /* 此处省去之前导入的HelloWorld模块 */

                  Vue.use(Router)export default new Router({routes: [{path: '/',component:resolve=>(require(["@/components/HelloWorld"],resolve))}]})
      
    • ES 提出的import方法,(------最常用------)
      import Vue from ‘vue’
      import Router from ‘vue-router’

      const HelloWorld = ()=>import("@/components/HelloWorld")Vue.use(Router)export default new Router({routes: [{path: '/',component:HelloWorld}]})
      

      组件懒加载

  • ES提出的import方法
    import Vue from ‘vue’
    import Router from ‘vue-router’

    Vue.use(Router)const HelloWorld = ()=>import("@/components/HelloWorld")
    export default new Router({routes: [{path: '/',name: 'HelloWorld',component:HelloWorld}]
    })
    
  • vue异步组件实现懒加载

    1111

    <script>
    export default {components:{"One-com":resolve=>(['./one'],resolve)},data () {return {msg: 'Welcome to Your Vue.js App'}}
    }
    </script>
    

五、总结:

路由和组件的常用两种懒加载方式:

1、vue异步组件实现路由懒加载

component:resolve=>([‘需要加载的路由的地址’],resolve)

2、es提出的import(推荐使用这种方式)

const HelloWorld = ()=>import(‘需要加载的模块地址’)

55.兼容性问题

条件注释:满足条件,下面代码JS链接就会生效;不满足条件的话,就是个注释;

  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --><!--解决ie9以下浏览器对html5新增标签的不识别,并导致CSS不起作用的问题--><!--解决ie9以下浏览器对 css3 Media Query  的不识别 --><!-- WARNING: Respond.js doesn't work if you view the page via file:// --><!-- 条件注释:解决小于IE9的版本一些问题 --><!--[if lt IE 9]><script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script><script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script><![endif]-->

56. Package.json

package.json是一个描述文件,描述了你项目中各个包之间的关系,作用如下

  1. 作为一个描述文件,描述了你的项目依赖哪些包
  2. 允许我们使用 “语义化版本规则”指明你项目依赖包的版本
  3. 让你的构建更好地与其他开发者分享,便于重复使用

快速生成一个package.json文件

$ npm init -y

57. query参数 和body参数

query参数 要放到 axios请求的 params里面 (get请求)

body参数 要放到 axios请求的 data里面 (post请求)

例如:

 methods: {// 添加 draft 值为true是草稿false是发表async addArticle (draft) {try {//本次传递给后台的数据,既有query参数,又有body参数,// 其中query参数放在url里面// 而body参数放在url的后面位置await this.$http.post(`articles?draft=${draft}`, this.articleForm)this.$message.success(draft ? '存入草稿成功' : '发表成功')this.$router.push('/article')} catch (e) {this.$message.error('操作失败')}}}

query

参数名称 是否必须 示例 备注
draft 否 true 或 false 是否存为草稿(true 为草稿)

body

名称 类型 是否必须 默认值 备注 其他信息
title string 必须 文章标题
content string 必须 文章内容
cover object 必须 封面
├─ type integer 必须 封面类型 -1:自动,0-无图,1-1张,3-3张
├─ images string [] 必须 item 类型: string
channel_id integer 必须 文章所属频道id

当get请求的参数query过长的时候,一个个的拼接在url上面是非常麻烦的,我们可以直接这样操作

async getArticles () {// 如果是post传参  放到请求主体提交body  axios.post(url, 请求体传参)// 如果是get传参  放到请求的地址?后面   axios.get(url, {params: 传参对象})const {data: { data }像post请求的一样,在url后面以一个对象的形式,写上我们的参数} = await this.$http.get('articles', { params: this.filterParams })this.articles = data.resultsthis.totals = data.total_count//   console.log(this.totals)}

58. 路径传参 ?号后面键值对传参 请求体传参

   async editArticle () {try {// ${this.$route.query.id}是路径传参  // ?draft=false 是问号后键值对传参//  this.articleForm 是请求体传参await this.$http.put(`articles/${this.$route.query.id}?draft=false`, this.articleForm)this.$message.success('修改成功')this.$router.push('/article')} catch (e) {this.$message.error('操作失败')}}

59.路由传参

  • 绑定编辑按钮的点击事件
  • 跳转到 发布文章 (承担编辑功能)
  • 携带 文章ID 做编辑的时候。
    • 怎么通过路由传参?

      • query ?后传参 ?id=100
      • params 路径后传参 /100 动态路由传参
    • 场景: /publish /publish/100 /publish?id=100

    • 结论:使用query

              <el-button @click="toEdit(scope.row.id)" plain type="primary" icon="el-icon-edit" circle></el-button>// 编辑文章
      toEdit (articleId) {this.$router.push(`/publish?id=${articleId}`)
      },
      

然后接收的组件则做如下操作:

 await this.$http.put(`articles/${this.$route.query.id}?draft=false`,

通过

this.$route.query.id  // 来接收数据

路由守卫:当跳转页面的时候被路由守卫拦截到登录页,要通过$router.currentRoute.path获取路由地址,然后通过路径才能回到原来的页面

console.log('路由地址', this.$router.currentRoute.path)

60.watch用法

  • 一般用法:首先监听data数据的变化
    data () {
    return {
    msg: ‘数据’,
    user: {
    name: ‘名字’,
    age: 10
    }
    }
    },
    watch: {
    // msg变化了就会触发这个函数
    msg (newVal,oldVal) {
    // newVal 改变后值,oldVal 改变前的值
    // 完成自己业务逻辑
    },
    // 数据是多层 user.name
    ‘user.name’ () {
    }
    }
    要是监听对象中某个键值的变化,那么就使用单引号将其引起来,这样才是合法的函数形式’user.name’
  • 监听路由变化的时候
    watch: {
    // 监听到 地址栏ID 数据的变化
    KaTeX parse error: Expected 'EOF', got '}' at position 65: … } }̲ 直接就是'route.query.id’,不需要使用this.$route.query.id

61.封装的组件如何调用

当我们封装好组件的时候,在单个页面进行调用的时候

  1. 在单页面进行导入
    import ComA from ‘@/test/com-a’
    import ComB from ‘@/test/com-b’
  2. 仍然在单页面中,注入到vue的子组件的components属性上面
    export default{
    components:{ComA,ComB}
    }
  3. 这样就可以在单页面的组件中进行使用了

62.路由配置

  1. 建立一个router.js的路由模块

    import VueRouter from ‘vue-router’// 导入router 必要模块
    import Vue from ‘vue’// 导入vue组件 必要模块 因为是js模块,所以要导入
    import Login from ‘@/views/login’// 导入login组件

    // 挂载到全局使用
    Vue.use(VueRouter) // 此处安装之后,在导入入口文件的时候就不需要在使用use安装

    const router = new VueRouter({ // 配置路由信息
    routes: [
    // 登录组件
    { path: ‘/login’, component: Login },
    // home组件及其子组件
    {
    path: ‘/’,
    component: Home,
    children: [ // 配置一级路由的子路由 二级路由
    // 欢迎界面
    { path: ‘/’, component: Welcome },
    // 内容管理
    { path: ‘/article’, component: Article },
    // 文章编辑
    { path: ‘/publish’, component: Publish },
    // 素材管理
    { path: ‘/image’, component: Image },
    // 评论管理
    { path: ‘/comment’, component: Comment }
    ]
    },
    // 404组件
    // 通配以上规则,所没有的地址
    { path: ‘*’, component: NotFound } // 通配路由
    ]
    })

    router.beforeEach((to, from, next) => { // 路由钩子 也就是路由守卫
    // console.log(store.getUser())
    // debugger
    // to 去哪里
    // from 来自哪里
    // next 放行|指定跳转路由
    // 判断如果是除去登录页面外,且当前没有登录,就把其他拦截到登录
    // debugger
    // console.log(!store.getUser().token)

    if (to.path !== ‘/login’ && !store.getUser().token) return next(’/login’)
    // - 其他情况都是放行
    next()
    })

    export default router // 最后导出 然后再入口文件也就是main.js里面引用

  2. 在main.js中引入配置封装的路由模块

    import router from ‘./router’
    new Vue({
    router,
    render: h => h(App)
    }).$mount(’#app’)

  3. 当我们路由配置好之后,在确定的位置加上

vue的路由就会自动根据我们配置好的路径进行显示组件

63.vue中自定义事件-传参

项目二中最后的缓存优化使用了自定义事件的传参

64.element-ui里面的slot-scope=’scope‘

关于slot-scope

一般都是使用在table表格中,而且是在表格需要添加组件中使用,其中scope.row代表的就是每一项数据,我们就可以直接在添加的组件中使用

65.链式导航 编程式导航

链式:

<template><router-link src=''></router-link></template>

编程式:

this.$router.push('路径')

66.vue中动态绑定class

  • 最简单的绑定(这里的active加不加单引号都可以,以下也一样都能渲染)
    :class="{ ‘active’: isActive }"
  • 判断是否绑定一个active
    :class="{‘active’:isActive==-1}"
    或者
    :class="{‘active’:isActive==index}"
  • 绑定并判断多个
    :class="[isActive==index?‘active’:‘otherActiveClass’]"
    {{ item.name }}
    判断activeIndex是否恒等于i,若是等于,这个元素绑定样式red
    class前面一定要加一个冒号:,这样才是动态绑定,因为有两个class,不然eslint就会报错Parsing error: duplicate-attribute
    分析错误:属性重复

67let和var的区别

  • 作用域 通过let定义的变量,作用域是在定义它的块级代码以及其中包括的子块中,并且无法在全局作用域添加变量。 通过var定义的变量,作用域为包括它的函数作用域或者全局作用域。

    function varTest() {var x = 1;if (true) {var x = 2;  // same variable!console.log(x);  // 2}console.log(x);  // 2
    }function letTest() {let x = 1;if (true) {let x = 2;  // different variableconsole.log(x);  // 2}console.log(x);  // 1
    }
    // let 无法在全局作用域中定义变量
    var x = 'global';
    let y = 'global';
    console.log(this.x); // "global"
    console.log(this.y); // undefined
    
  • 重复声明 通过let定义的变量,在同一个作用域内,不可以重复声明。 通过var定义的变量,在同一个作用域内,重复声明,在生成执行上下文的时候,会无视后面的声明。
    // 报错
    (function () {
    let a = 10;
    var a = 1;
    console.log(a)
    })()
    // 报错
    (function () {
    let a = 10;
    let a = 1;
    console.log(a)
    })()
    // 报错
    (function () {
    var a = 10;
    var a = 1;
    console.log(a) // 1
    })()

  • 临时死区引起的提升等问题
    我们知道在代码执行之前,会先扫描所有域内的var声明的变量,将其先进行初始化为undefined,然后再执行代码,也就是所谓的“提升”现象。
    但对于let声明的变量而言,则有所不同。在代码执行之前的扫描,同样也会对let变量进行“提升”,但并没有将其置为undefined。let定义的变量虽然经历了提升,但在没有执行到初始化它的代码前,该变量并没有被初始化,如果此时访问的话,会被置为ReferenceError错误。从代码块开始到执行到let变量初始化完毕这段时间,let变量已经被声明,但不可访问。这段时间被成为临时死区。下面是几个典型的展示临时死区问题的代码:

68const的声明问题

  • const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心
  • 如果真的想将对象冻结,应该使用Object.freeze方法。

69 0.1+0.2等于多少

  • 由于0.1转换成二进制时是无限循环的,所以在计算机中0.1只能存储成一个近似值。另外说一句,除了那些能表示成 x/2^n 的数可以被精确表示以外,其余小数都是以近似值得方式存在的。
  • 在0.1 + 0.2这个式子中,0.1和0.2都是近似表示的,在他们相加的时候,两个近似值进行了计算,导致最后得到的值是0.30000000000000004,此时对于JS来说,其不够近似于0.3,于是就出现了0.1 + 0.2 != 0.3 这个现象。 当然,也并非所有的近似值相加都得不到正确的结果。
  • 0.1+0.2 => (0.1*10+0.2*10)/10
    

什么是堆什么是栈

首先说明一下,本文说到的堆、栈不是数据结构中的堆、栈,而是内存使用中的堆和栈。

栈区(stack)——由编译器自动分配释放,存储函数的参数值,局部变量的值等,其操作方式类似于数据中的栈,先进先出。堆区(heap)——一般由程序员分配释放,若程序员不分配也就没有堆,不释放,程序结束时可能由OS回收。

区别和联系:

1、申请方式

堆:由程序员自己申请并指明大小的,在c中malloc函数 如p1 = (char *)malloc(10);栈:系统自动分配的,如声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间

2、申请后系统的响应动作

堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会 遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内 存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大 小,系统会自动的将多余的那部分重新放入空闲链表中。栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

3、申请大小的限制

堆:由低地址到高地址扩展的数据结构,是不连续的内存区域,这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。栈:在windows下,栈是由高向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是 一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。

4、申请效率

堆:由类似new机制来分配内存,一般速度比较慢,而且容易产生内存碎片,这一点从分配机制上能解释,不过用起来比较方便。栈:由系统自动分配,速度比较快,而且程序员是无法控制的。

5、时效性

堆:持久化栈:临时

6、上下文调用

堆:全局栈:局部

行内元素和行内块元素有什么区别

1.行内元素bai与块级函数可以相互转换,通du过修改display属性值来切zhi换块级元dao素和行内元素,行内元素display:inline,块级元素display:block。

2.行内元素和其他行内元素都会在一条水平线上排列,都是在同一行的;块级元素却总是会在新的一行开始排列,各个块级元素独占一行,垂直向下排列,若想使其水平方向排序,可使用左右浮动(float:left/right)让其水平方向排列。

3.行内元素不可以设置宽高,宽度高度随文本内容的变化而变化,但是可以设置行高(line-height),同时在设置外边距margin上下无效,左右有效,内填充padding上下无效,左右有效;块级元素可以设置宽高,并且宽度高度以及外边距,内填充都可随意控制。

4.块级元素可以包含行内元素和块级元素,还可以容纳内联元素和其他元素;行内元素不能包含块级元素,只能容纳文本或者其他行内元素。

es6数组有哪些遍历方法

  • forEach
  • map
  • filter
  • some
  • every
  • reduce

同步任务和异步任务有哪些区别

又回到了最初的起点——javascript是单线程。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。于是就有一个概念——任务队列。如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。于是JavaScript语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。

于是,所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。

具体来说,异步运行机制如下:

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。

什么是promise

Promise 是一种解决异步编程的方案,相比回调函数和事件更合理和更强大。

从语法上讲,promise是一个对象,从它可以获取异步操作的消息;

二、promise有三种状态:pending 初始状态也叫等待状态,fulfiled成功状态,rejected失败状态;状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

三、Promise的两个特点

1、Promise对象的状态不受外界影响

2、Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,

四、Promise的三个缺点

1)无法取消Promise,一旦新建它就会立即执行,无法中途取消

2)如果不设置回调函数,Promise内部抛出的错误,不会反映到外部

3)当处于pending(等待)状态时,无法得知目前进展到哪一个阶段,是刚刚开始还是即将完成

promise是用来解决两个问题的:

1.回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象

2.promise可以支持多并发的请求,获取并发请求中的数据

这个promise可以解决异步的问题,本身不能说promise是异步的

三栏布局方式两边固定中间自适应

  1. margin负值法:左右两栏均左浮动,左右两栏采用负的margin值。中间栏被宽度为100%的浮动元素包起来
  2. 自身浮动法:左栏左浮动,右栏右浮动,中间栏放最后
  3. 绝对定位法:左右两栏采用绝对定位,分别固定于页面的左右两侧,中间的主体栏用左右margin值撑开距离。

4.flex 左右固定宽 中间flex:1

首屏加载慢的原因:

第一次加载页面有很多组件数据需要渲染

解决方法:

1.路由懒加载 component:()=>import(“路由地址”)

2.ui框架按需加载

3.gzip压缩

白屏时间检测:

????

解决白屏问题:

①使用v-text渲染数据

②使用{{}}语法渲染数据,但是同时使用v-cloak指令(用来保持在元素上直到关联实例结束时候进行编译),v-cloak要放在什么位置呢,v-cloak并不需要添加到每个标签,只要在el挂载的标签上添加就可以

Js中常见的内存泄漏

1.意外的全局变量

2.被遗忘的计时器或回调函数

3.脱离DOM的引用

4.闭包

Js的函数节流和函数防抖的区别

函数节流是指一定时间内js方法只执行一次。

函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次

函数节流是 声明一个变量当标志位,记录当前代码是否在执行,如果正在执行,取消这次方法执行,直接return,如果空闲,正常触发方法执行

函数防抖是需要一个延时器来辅助实现,延迟执行需要执行的代码,如果方法多次触发,把上次记录的延迟执行代码用cleartimeout清除掉,重新开始,如果计时完毕,没有方法来访问触发,则执行代码

请简述vue的单向数据流

父级prop的更新会向下流动到子组件中,每次父组件发生更新,子组件所有的prop都会刷新为最新的值

数据从父组件传递给子组件,只能单向绑定,子组件内部不能直接修改父组件传递过来的数据,(可以使用data和computed解决)

Vue循环的key作用

Key值的存在保证了唯一性,Vue在执行时,会对节点进行检查,如果没有key值,那么vue检查到这里有dom节点,就会对内容清空并赋新值,如果有key值存在,那么会对新老节点进行对比,比较两者key是否相同,进行调换位置或删除操作

Vue双向绑定的原理

Vue双向绑定就是:数据变化更新视图,视图变化更新数据

Vue数据双向绑定是通过数据劫持和观察者模式来实现的,

数据劫持,object.defineproperty它的目的是:当给属性赋值的时候,程序可以感知到,就可以控制改变属性值

观察者模式 当属性发生改变的时候,使用该数据的地方也发生改变

Bootstrap的原理

网格系统的实现原理,通过定义容器大小,平分12份,(24份或者32份),再调整内外边距,结合媒体查询,就成了强大的响应式网格系统。

比如 row col-xs-4

40.计算属性与watch区别

Computed watch 区别就是computed的缓存功能,当无关数据数据改变时,不会重新计算,直接使用缓存中的值。计算属性是用来声明式的描述一个值依赖了其他的值,当所依赖的值后者变量发生变化时,计算属性也跟着改变,

一个变量影响多个变量

Watch监听的是在data中定义的变量,当该变量变化时,会触发watch中的方法

多个变量影响一个变量

请简述webpack中的loaders与plugin的区别

什么是loaders,loaders是文件加载器,能够加载资源文件,并对这些文件进行处理,例如,编译,压缩等,最终一起打包到指定文件中。

什么是plugin,在webpack运行的生命周期会有许多事件,plugin可以监听这些事件

区别:加载器是用来加载文件的,webpack本身只能加载js文件(内置babel-loader),加载其他文件就需要安装别的loader,比如:css-loader file-loader

Plugin是扩展webpack功能的,通过plugin ,webpack可以实现loader不能完成的复杂功能

说一下对websocked的理解

Websocked是一种双向通信协议,在建立连接后,websocked服务器和浏览器都能主动向对方发送或者接收数据,websocked需要类似于tcp的客户端和服务器通过握手连接,连接成功后才能互相通信

后台传递过来的数据是那些

什么是作用域,什么是作用域链

作用域:变量起作用的范围

    * js中只有两种:全局作用域  局部作用域*1.全局作用域:变量在任何地方起作用* 全局变量:在函数外面声明2.局部作用域:变量只能在函数内部起作用局部变量:在函数内部声明
  • 1.作用域链是怎么来的

    • 默认情况下,我们的js代码处于全局作用域,当我们声明一个函数时,此时函数体会开辟一个局部作用域, 如果我们在这个函数体中又声明一个函数,那么又会开辟一个新的局部作用域,以此类推,就会形成一个作用域链
  • 2.变量在作用域链上的访问规则
    • 就近原则:访问变量时,会优先访问的是在自己作用域链上声明的变量,如果自己作用域链上没有声明这个变量,那么就往上一级去找有没有声明这个变量,如果有就访问,如果没有就继续往上找有没有声明,直到找到0级作用域链上,如果有,就访问,如果没有就报错

2021年前端面试题总结相关推荐

  1. 2021年前端面试题(附带答案)

    (答案不唯一,仅供参考,文章最后有福利) 前端面试汇总(2021年) 大纲 1.前言 2.前端工程化 3.前端设计模式 4.前端安全性问题 5.前端跨域问题 6.前端数据加密 7.前端http相关问题 ...

  2. 2021年前端面试题及答案

    前端面试汇总(2020年) 一 大纲 1.前言 2.前端工程化 3.前端设计模式 4.前端安全性问题 5.前端跨域问题 6.前端数据加密 7.前端http相关问题 8.*前端基础知识点面试题 9.前端 ...

  3. 2023年前端面试题集锦

    2023年前端面试题集锦 包括内容: 一. 计算机网络.HTML.浏览器相关 二. CSS相关 三. js相关 四.前端性能优化点 五.前端整体框架体系学习 一. Http.HTML.浏览器相关 1. ...

  4. 2021前端面试题系列:fetch与axios、浏览器内多个标签页面通信及安全问题

    大家好,我是前端岚枫,今天主要跟大家分享我整理的笔记2021前端面试题系列:fetch与axios.浏览器内标签页之间的通讯方法.XSS 和CSRF以及如何防范,此方面内容在我们的工作中常用到, 也是 ...

  5. 2021前端面试题系列:HTTP请求和HTTP缓存控制

    大家好,我是前端岚枫,一枚二线城市的程序媛,今天主要跟大家分享我整理的笔记2021前端面试题系列:HTTP请求和HTTP缓存控制,此方面内容在我们的工作中常用到, 也是面试官经常提问的问题,希望下面文 ...

  6. 2022年前端面试题整理,持续更新中

    端面试题整理 已同步到掘金.CSDN 掘金地址: https://juejin.cn/post/7075332630417244173 CSDN 地址:https://blog.csdn.net/z1 ...

  7. 2021前端面试题汇总——查漏补缺

    博主最近在持续面试(被虐)中,本片文章将持续更新 系列文章 大厂前端面试题总结(CSS篇) 大厂前端面试题总结(ES6篇) 大厂前端面试题总结(Vue篇) 大厂前端面试题总结(浏览器篇) 大厂前端面试 ...

  8. 2023年前端面试题考点之 通信(渲染、http、缓存、异步、跨域、安全)

    合集:2023年最全前端面试题考点HTML5+CSS3+JS+Vue3+React18+八股文+手写+项目+笔试_参宿7的博客-CSDN博客 本章内容为一面基础面 为了简洁,相关文章参考链接在标题里 ...

  9. 2017年前端面试题最新汇总

    再来更新一篇面试题 早前我更新过一篇 <前端面试题>,据反馈,确实帮助到了不少去面试的新人或者换工作的菜鸟 他们留言或者直接赞赏表示感谢,还有问答案的,不过我想说:我就是不给你答案,自有原 ...

最新文章

  1. R语言计算回归模型每个样本(观察、observation、sample)的杠杆值(leverage)实战:如果一个样本的预测变量比其他样本的预测变量值更极端,那么被认为具有很高的杠杆作用
  2. 对外星智能的搜索得到了重大的升级
  3. 单片机18b20c语言程序,AVR单片机控制DS18B20的示例C程序
  4. windows下 sqlplus / as sysdba 报ora-12560的终极解决方法
  5. 收藏!40 个 CSS 布局技巧
  6. Windows 聚焦的锁屏壁纸设置为桌面壁纸
  7. 燕山大学计算机专业研究生怎么样,求助大家!重庆邮电大学计算机专业的研究生值得一读吗?...
  8. flock lock ex php,php – flock有可能用LOCK_EX返回false吗?
  9. 一些关于ROS中move_base的理解
  10. 【OpenGL】顶点变换常用函数总结
  11. php执行cmd/shell命令 木马小后门
  12. 使用Attribute简单地扩展WebForm
  13. pandas 调整列的顺序
  14. 《魔兽世界》中的小背景
  15. sigset 与 signal的区别?
  16. 缓冲区溢出基础实践(二)——ROP 与 hijack GOT
  17. Proteus 8.1 51单片机仿真双人对战五子棋
  18. Java篇 - 最全BigInteger和BigDecimal实战
  19. PC市场如何再起波澜?荣耀的创新或是答案
  20. listen的第二个参数

热门文章

  1. 自动清理 ES 历史数据
  2. 基于ARM的嵌入式linux 内核的裁剪与移植
  3. 3种方式实现瀑布流布局
  4. 汇总二,js系列-css系列-其他综合系列
  5. 图像传感器噪声建模与分析
  6. 又一世界级人工智能大会即将开幕!
  7. android4.0的手机,高中低全覆盖 各价位Android4.0手机推荐
  8. 鸿蒙系统p50什么时候上市,华为P50Pro和MatePad Pro2什么时候上市 搭载鸿蒙系统吗...
  9. 薪资17K是一个怎样的水平?来看看98年测试工程师的面试全过程…
  10. 莲花——安妮宝贝§2006-03-01出版