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-pick7fcb3defff 命令,就把该条commit记录合并到了master分支,这只是在本地合并到了master分支;最后,git push 提交到master远程,至此,就把develop分支的这条commit所涉及的更改合并到了master分支。2.redux和vuex的区别
vuex是吸收了Redux的经验并且对redux的进行了调整,从而对仓库的管理更加明确,vuex还放弃了一些特性做了一些优化,代价是只能和vue配合
vuex有自动渲染的功能,所以不需要更新
Redux 是一个状态管理系统
3.跨域问题
出现跨域问题的原因:
在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问问题。在请求的过程中我们要想回去数据一般都是post/get请求,所以..跨域问题出现
什么是同源策略:
同源策略 是由NetScape提出的一个著名的安全策略。所谓的同源,指的是协议,域名,端口相同。浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。
受同源策略(SOP)的影响,协议 域名 端口
通过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提供公开服务。
跨域资源共享(CORS)
在服务器Response Header,响应头中的Access Control Allow Origin为对应的域名,后台更改header
3.用http-proxy-middleware(配置代理服务器的中间件)
4. 前端优化问题
减少http请求的次数,精灵图 本地缓存 函数防抖节流
图片懒加载
少用全局变量、缓存DOM节点查找的结果
少操作Dom,可以一次性运行完,然后再操作Dom节点
优化CSS(压缩合并css,如 margin-top, margin-left…)
网址后加斜杠(如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
7.ajax
是一种无需重新加载整个网页的情况下,能够更新部分网页的技术
原生ajax:
1)创建Ajax引擎对象
2)为Ajax引擎对象绑定监听(监听服务器已将数据响应给引擎)
4)发送请求
5)接受响应数据
get
参数拼接在url(url?name=1&age=30),在xhr.open()第二个参数中处理
由于浏览器对url长度的支持(各个浏览器均不同)是有限制,所以,它只能附加少量的数据。
post
要设置请求头: xhr.setRequestHeader(‘content-type’,’application/json’)
参数写在send()方法中:send(‘对象字符串’)
相对于get 来说,没有传参大小的限制。
jQuery中的ajax:
$.ajax({ * type : “POST”, //提交方式 * url : “${pageContext.request.contextPath}/org/doDelete.action”,//路径 * data : { “org.id” : “${org.id}” },//数据,这里使用的是Json格式进行传输 * success : function(result) {//返回数据根据结果进行相应的处理 if ( result.success ) { $(“#tipMsg”).text(“删除数据成功”); tree.deleteItem(“${org.id}”, true); } else { $(“#tipMsg”).text(“删除数据失败”); } } });
下面的写法是对jQuery ajax的再一次封装
$.get(url,[data],[fn],[type])$.post(url,[data],[fn],[type])
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元素内
模板引擎 :数据量比较小的时候用模板字符串,数据量大的时候用模板引擎
步骤:
将我们要渲染的模板单独放到一个script标签里面
<script type=’text/html’ id=’moban’> // 告诉浏览器这一段要以html解释,不然会报错// 这里面放入我们要遍历的模板</script>
我们要给模板加一个id,这样才能找到模板
调用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 ContentGET范围请求已成功处理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.大数字的处理方式
大数字的范围-2^53~2^53
可以使用插件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
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
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.js22.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) //undifindconsole.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)} }) } )}// 这时候我们在调用封装的promisegetContent(‘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请求
其实都可以统称为请求配置
请求配置 :请求拦截器(一般在请求头配置请求头) 响应拦截器
transformResponse这是在响应拦截器之前发挥作用,一般用来处理大数字
28.原生放大镜28.1 animate函数封装
原生轮播图 思想:排他思想
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。
Dreamweaver中有两种不同的发布视频的方式(视频类型“选项)
累进式下载视频:首先将FLV文件下载到访问者的硬盘上,当下载了足够多的视频文件后就开始播放,它允许下载完成之前就开始播放视频文件。
优点:
服务器上不需要安装除了web服务器(apache或iis)以外的软件。
只要跟其他WEB资源一样,把视频传到服务器上即可。
缺点:
无法认证用户,不能管理和报告视频被下载的总量,也不能降低单个用户的可用带宽。
视频文件会被web浏览器缓存到用户电脑上,用户可以找到缓存里的视频文件并另存,这样就很难限制视频文件的传播。
流视频:Flash Player链接到服务器,视频以流的形式传播,当收到信息后,会显示出来,然后就从内存中消除,它从不保存到用户磁盘上。
优点:
可以及时回放视频,而不需要等下载一定多的量后才播放。
可以验证用户,只有授予权限的用户才能访问视频。
可以根据用户和视频文件分配带宽。
视频文件不会被浏览器缓存,所以能控制传播。
HTML5 DOM 为 <audio> 音频和 <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.2:第二种就是我目前需求所需要的,可以在H5页面中嵌入第三方视频的方法。这里以优酷视频为例,首先在iframe的src中填写优酷视频引用链接,格式如下:
http://player.youku.com/embed/XMzcwNTY3NTM2MA
绿色部分是优酷通用的引用链接(不用修改),红色部分填写你想嵌入视频的ID。(下方有获取优酷视频ID的教程
32.C3和H5新特性
H5的新特性
1.语义化标签
有利于SEO,有助于爬虫抓取更多的有效信息,爬虫是依赖于标签来确定上下文和各个关键字的权重。
语义化的HTML在没有CSS的情况下也能呈现较好的内容结构与代码结构
方便其他设备的解析
便于团队开发和维护
2.表单新特性
3.多媒体视频(video)和音频(audio)
4.web存储
sessionstorage:关闭浏览器清空数据,储存大小约5M。
localstorage:永久生效,存储大小20M,多窗口下都可以使用
都只能储存字符串
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.背景:
通过 background-size 设置背景图片的尺寸。
通过 background-origin 可以设置背景图片定位(background-position)的参照原点。
通过background-clip,可以设置对背景区域进行裁切,即改变背景区域的大小。
7.渐变:线性渐变 linear-gradient,径向渐变radial-gradient
8.字体图标
9.伸缩盒子:调整主轴对齐justify-content,调整侧轴对齐align-items,伸缩分配flex,正序方式排序order
10.2D转换:
translate 设置元素的位置(x/y坐标)
scale 设置元素的缩放比例(x/y两个方向)
rotate 设置元素旋转(正值为顺时针,负值为逆时针)
transform-origin 设置转换元素的原点
11.3D转换:
透视(perspective)值为1000px~1200px
将2D元素转换为3D立体(给父元素设置)transform-style: perserve-3d;
设置元素背面是否可见 backface-visibility: hidden;
12.动画:
定义关键帧 @keyframes
通过百分编写帧
在各帧中分别定义各属性
通过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)
第一个是not|only mediatype 媒体类型 常用的有all所有设备 print打印机 screen电脑手机
add|not|only 关键字 连接第一个和第三个的关键词
media feature 媒体特性 必须用小括号包裹 里面写
示例:
<style> @media screen and (max-width:800px){ background-color:pink } // 页面宽度小于800px的时候显示的样式 @media screen and (min-width:800px) and (max-width:960px){ background-color:blue } // 范围宽度,页面宽度是800px~960px的时候显示蓝色 </style>
max-width 页面最大可见区域宽度 小于等于
min-width 页面最小可见区域宽度
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>
通过媒体查询进行判断屏幕尺寸,
当小于640大于320的时候,我们可以通过样示,让他们宽度100%,两行顶满
当大于640的时候,我们可以通过样式让两个兄弟div,通过浮动,宽度设置为50%,一行显示
rem适配方案1:(划分为15等份)
页面元素的rem值=页面元素值(px)/(屏幕宽度/划分的分数)
屏幕宽度/划分的分数 就是html font-size的大小
因此:页面元素的rem值=页面元素值(px) / html font-size 字体的大小
rem适配方案2:(划分为10等份)
下载flexible
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的值应该从父元素继承)
如果你创造了一个 <div> 没有设置 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}),那么我们创建一个和上段中相同设置的 <div> 容器时,那么他的最终宽度即为 100px, 那么它的内容部分(content)的有效宽度变成了 100px-2*10px-2*10px =60px; 所以你会得到一个你预期大小的盒子容器,但是只是被压缩了内容部分尺寸而已,但是对于整体布局而言益处颇多。所以要合理利用好这个属性,这个属性十分重要。
35.数组方法
push( ) 向数组的末尾添加一个新元素
unshift( ) 向数组的开头添加一个新元素
pop( ) 删除数组的最后一个元素
shift( ) 删除数组的第一个元素
cancat( ) 合并数组
reverse( ) 将一个数组中的元素的顺序反转排序
slice(1,3) 从一个数组中选择元素 // 获取下标为1,2的元素
join( ) 用数组的元素组成字符串 join可以指定连接字符
var arr=[123,456,789]undefinedarr.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});)36. 字符串方法
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; else newObj[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”);// 出现最多的字符:econsole.log(“出现最多的字符:” result.maxkey);// 出现次数:2console.log(“出现次数:” result.maxvalue);
创建一个对象
var newObj = {};
然后添加我们添加一个键值
newObj[‘字符串样式的键名’]=1// 就相当于下面这种形式newObj.键名=1
以上这两种写法是等价的
38.深拷贝 浅拷贝
原生递归的方法
json的方法
jquery的extend方法
39. 变量提升
变量提升:函数声明和变量声明总是会被解释器悄悄地被”提升”到方法体的最顶部。
JavaScript 只有声明的变量会提升,初始化的不会。(初始化的意思就是变量在定义的时候就被赋值)
40.引用传递 值传递
引用传递:函数调用中传递是对象,数组,一般称为引用传递
值传递:函数调用中,传递的是一个数值,我们称为值传递
//**值传递** <script> var n =10 function fun(n) { // 在函数中开辟了一个空间a==10 相当于var a=5 n ; // 11 console.log(n); 11 } fun(n); // 结果是函数没有改变全局变量n的值,所以结果依旧是10 console.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时候,会导致父盒子出现塌陷问题
解决办法:
给父盒子设置一个透明的上边框
border-top:1px solid transparent
给父元素定义上内边距
padding:1px
给父元素添加overflow:hidden
45.css浮动
就是float:left/right/none(默认不浮动)
浮动可以让块元素在一行显示
特点:
浮动元素会脱离标准流
浮动元素会一行内显示并且元素顶部对齐
浮动元素会具有行内块元素特性
缺点:
子元素浮动脱标,父元素未设置高度的话会出现问题,父元素的兄弟元素会顶上来
解决办法:
额外标签法也称为隔墙法 缺点:结构较差
在浮动元素末尾添加一个空标签,例如:<div style=’clear:both’></div>
父级添加overflow属性 缺点:无法显示溢出的部分
overflow:hidden/auto/scroll
父级添加after伪元素
: after{ }
父级添加双伪元素
46.精灵图使用
移动背景图片,使用background-position
使用步骤:
首先用切片工具定位小图片图片位置
然后css里面写上
47.字体图标使用
首先通过阿里矢量图把字体图标下载过来
引入到页面当中,通过@font-face{ 一大串}
打开demo.html ,里面有我们需要字体图标的编码,打开后就直接复制到我们需要放置的标签中
我们在标签的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’
简单使用:
首先我们在@keyframes 动画名称{ 里面写上 0%{ 开始位置} 100%{结束位置}} 0% 100%也可以用from to表示
调用动画,在我们需要动画的标签css里面写入 animation-name:动画名 animation-duration:动画花费的时间
52.less使用
变量:less可以定义一个变量,然后在其他地方使用即可
@color:yellow;body{ background-color:@color;}
必须有@为前缀
不能包含特殊字符
不能以数字开头
大小写敏感
我们使用esay less插件,然后再保存less文件,这样就自动生成css文件
嵌套:子元素直接嵌套到父元素内部即可,如果有伪类,我们可以直接在冒号前加一个&
div{ .img{ &:hover{ color:yellow } }}
运算
53.全局安装 本地安装
运算符(*)乘号 和(/)除号
运算符左右空格隔开
对于两个不同单位的值之间的运算,运算结果的值取第一个值的单位
如果两个值之间只有一个值有单位,则运算就取该单位
本地安装 –save-dev –save
开发依赖 –save-dev 大写的为:-D
生产依赖 –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异步组件实现懒加载
<template> <div class=”hello”> <One-com></One-com> 1111 </div></template><script>export default { components:{ “One-com”:resolve=>([‘./one’],resolve) }, data () { return { msg: ‘Welcome to Your Vue.js App’ } }}</script>
五、总结:
路由和组件的常用两种懒加载方式:
1、vue异步组件实现路由懒加载
2、es提出的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是一个描述文件,描述了你项目中各个包之间的关系,作用如下
作为一个描述文件,描述了你的项目依赖哪些包
允许我们使用 “语义化版本规则”指明你项目依赖包的版本
让你的构建更好地与其他开发者分享,便于重复使用
快速生成一个package.json文件
$ npm init -y57. 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
名称类型是否必须默认值备注其他信息titlestring必须文章标题contentstring必须文章内容coverobject必须封面├─ typeinteger必须封面类型 -1:自动,0-无图,1-1张,3-3张├─ imagesstring []必须item 类型: stringchannel_idinteger必须文章所属频道id
当get请求的参数query过长的时候,一个个的拼接在url上面是非常麻烦的,我们可以直接这样操作
query ?后传参 ?id=100
params 路径后传参 /100 动态路由传参
怎么通过路由传参?
场景:/publish /publish/100 /publish?id=100
结论:使用query
然后接收的组件则做如下操作:
await this.$http.put(`articles/${this.$route.query.id}?draft=false`,
通过
this.$route.query.id // 来接收数据
60.watch用法
一般用法:首先监听data数据的变化
data () { return { msg: ‘数据’, user: { name: ‘名字’, age: 10 } }},watch: { // msg变化了就会触发这个函数 msg (newVal,oldVal) { // newVal 改变后值,oldVal 改变前的值 // 完成自己业务逻辑 }, // 数据是多层 user.name ‘user.name’ () { } }
要是监听对象中某个键值的变化,那么就使用单引号将其引起来,这样才是合法的函数形式’user.name’
监听路由变化的时候
直接就是’$route.query.id’,不需要使用this.$route.query.id
61.封装的组件如何调用
当我们封装好组件的时候,在单个页面进行调用的时候
在单页面进行导入
import ComA from ‘@/test/com-a’import ComB from ‘@/test/com-b’
仍然在单页面中,注入到vue的子组件的components属性上面
export default{ components:{ComA,ComB}}
这样就可以在单页面的组件中进行使用了
<template> <div> <com-a></com-a> <com-b></com-b> </div></template>
62.路由配置
建立一个router.js的路由模块
在main.js中引入配置封装的路由模块
import router from ‘./router’new Vue({ router, render: h => h(App)}).$mount(‘#app’)
当我们路由配置好之后,在确定的位置加上
<router-view></router-view>
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’]”<span :class=”{red: i === activeIndex}” class=’f12′>{{ item.name }}</span>
判断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 variable console.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的声明问题
如果真的想将对象冻结,应该使用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、申请后系统的响应动作
堆:由类似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)的任务,只有等主线程任务执行完毕,”任务队列”开始通知主线程,请求执行任务,该任务才会进入主线程执行。
具体来说,异步运行机制如下:
什么是promise
Promise 是一种解决异步编程的方案,相比回调函数和事件更合理和更强大。从语法上讲,promise是一个对象,从它可以获取异步操作的消息;二、promise有三种状态:pending 初始状态也叫等待状态,fulfiled成功状态,rejected失败状态;状态一旦改变,就不会再变。创造promise实例后,它会立即执行。三、Promise的两个特点1、Promise对象的状态不受外界影响2、Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,四、Promise的三个缺点1)无法取消Promise,一旦新建它就会立即执行,无法中途取消2)如果不设置回调函数,Promise内部抛出的错误,不会反映到外部3)当处于pending(等待)状态时,无法得知目前进展到哪一个阶段,是刚刚开始还是即将完成
三栏布局方式两边固定中间自适应
margin负值法:左右两栏均左浮动,左右两栏采用负的margin值。中间栏被宽度为100%的浮动元素包起来
自身浮动法:左栏左浮动,右栏右浮动,中间栏放最后
绝对定位法:左右两栏采用绝对定位,分别固定于页面的左右两侧,中间的主体栏用左右margin值撑开距离。
4.flex 左右固定宽 中间flex:1
5.网格布局
首屏加载慢的原因:
第一次加载页面有很多组件数据需要渲染
解决方法:
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级作用域链上,如果有,就访问,如果没有就报错