HTML5 的新特性
- 语义化标签:header、footer、section、nav、aside、article
- 音频视频:audio、video
- canvas
- 地理定位:
- 拖拽:drag
- 本地存储:localStorage、sessionStorage
- WebSocket
http请求方式
get和post的区别
1.传递参数方式不同
2.传输数据大小不同,get(几k)
3.post比get更安全
4.产生数据包:get是header和data一起发送,post是先发送header,响应100后再发送data。个别浏览器post只发送一次,比如Firefox火狐
http和https的区别
1.HTTP默认使用80端口,这个端口指的是服务器端的端口,而客户端的端口是动态分配的。当我们没有指定端口访问时,浏览器会默认帮我们添加80端口。我们也可以自己指定访问端口。需要注意的是,现在大多数访问使用HTTPS协议,而HTTPS的默认端口为443,如果使用80端口访问,HTTPS协议的服务器可能会被拒绝。
localStorage,sessionStorage,cookie 的区别
本地存储方法有Cookie和h5的WebStorage
共同点:都是保存在浏览器端。
区别:
(1) 存储大小限制不同
cookie数据不能超过4k,sessionStorage和localStorage 比cookie大得多,可以达到5M或更大。
(2) 数据有效期不同
sessionStorage:仅在当前浏览器窗口关闭前有效。
localStorage:长期有效,直到用户删除。
cookie:在设置的cookie过期时间之前一直有效,默认为浏览器关闭。
(3) 作用域不同
cookie和localStorage,同源,同浏览器,可以在不同页面共享。
sessionStorage:同源,同浏览器,同一个页面。
(4) cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
sessionStorage非常少用,一般用localStorage
浏览器输入url后发生了什么
1.DNS解析、2.TCP连接、3.发送http请求、4.处理请求返回的数据、5.页面渲染、6.关闭连接
dns其实是域名解析服务器,因为域名是要解析成ip地址的,所以要使用dns解析。
TCP是传输控制协议,http协议就是基于tcp协议的。在传输数据之前,必须通过tcp连接进行3次握手来初始化。
https协议
https协议就是http协议加上SSL协议,传输的数据是经过加密的,比http更安全。
https传输过程:
1.首先经过TCP三次握手建立连接,然后开始SSL通信
2.客户端首先发送ssl信息和加密算法到服务器
3.服务器返回ssl信息
4.然后开始验证,验证通过后进行HTTP数据传输。
什么是浏览器缓存?
浏览器缓存就是浏览器会缓存当前页面,当你下次访问这个页面的时候会先查看浏览器缓存是否有该页面,而不是马上请求服务器
HTML文件的DOCTYPE有什么作用?
告诉浏览器的解析器要使用哪种HTML规范来解析页面。
ajax
ajax:异步的js和xml。就是在利用js操作浏览器的XMLHttpRequest对象来与服务器进行数据交互的方式。
ajax可以使网页在不刷新的情况下实现局部更新数据。
URL组成
由通讯协议、域名/IP地址、资源存放路径组成。
URL编码
作用:为了保证发送给服务器的url以及参数不会被服务器解析错误。比如你想传递的参数有中文,那就要进行url编码。
方法:编码:encodeURL()、解码:decodeURL()
JSON
json字符串是一种数据格式,一般服务器响应回来的数据格式都是json格式。
我们经常会用json的序列化(parse)和反序列化(stringify)来拷贝数据。
跨域
造成跨域主要是因为浏览器的同源策略。为了保证用户信息的安全,浏览器会禁止不同源的两个域进行访问。如果协议、域名、端口有一个不相同则为不同源,也就是跨域。不同源的话我们是无法共享cookie、localStorage等本地资源,以及不能发送请求和操作dom。
但我们在使用ajax的时候会经常跨域,所以有以下几种解决跨域的方法:
1.使用CORS,也就是跨域资源共享,不过这都是后台在服务器进行设置就可以了
2.使用JSONP跨域,所有浏览器都可以使用这个方法进行跨域,但它只支持get请求。
jsonp跨域原理:因为script标签和img标签的src是可以进行跨域请求的。所以jsonp跨域就是利用在script标签的src属性添加回调的函数名,然后就会发送一个get请求到服务器,服务器解析后会找到对应的函数去做这个回调,然后把数据返回。
介绍一下xhtml和html的区别是什么?
html是超文本标记语言,xhtml就是可扩展超文本标记语言,xhtml表现方式和html类似,但在语法上更加严格,例如:所有标签必须闭合和小写,所有参数值包括数字都要加引号。
用html的经验解决seo优化问题
SEO是英文Search Engine Optimization的缩写,中文译为“搜索引擎优化”。
html进行seo的几种方法:
1.给a标签添加title,给图片添加alt,合理使用keywords,description标签。
2.合理使用h标签,一个页面只能有一个h1标签。合理使用h5新增标签:section,article。
3.关键字使用strong标签,列表使用ul/ol。
CSS--------------------------------------------------------------------
css盒模型
css盒模型包括content,padding,border,margin。
两种盒模型的区别:
1.W3C盒模型 box-sizing:content-box的特点:通过css设置的宽高只是content的宽高
2.IE盒模型 box-sizing:border-box的特点:通过css设置的宽高是content+padding+border的宽高
六种实现元素水平居中方法
- 固定宽度 + margin:0 auto
- 父元素text-align:center
- 绝对定位+负外边距(有宽度)
- 绝对定位+transform:translate(-50%,-50%)(无宽度)
- display:flex,justify-content:center
实现元素垂直居中方法
- 行高等于高度
- 绝对定位+负外边距(有高度)
- 绝对定位+transform:translate(-50%,-50%)(无高度)
4.父元素:display:flex,align-items:center
5.父元素:display:flex,flex-direction:column,justify-content:center
如果盒子是浮动,父类没有高度,怎么解决?(清除浮动)
清除浮动的3种方法:
- 父级元素添加overflow:hidden。
- 伪元素清除浮动:
.clearfix:after{
content:'';
display:block;
height:0;
clear:both;
visibility:hidden;
}
.clearfix{
*zoom:1
/*zoom 1 就是ie6 清除浮动方式 * ie7以下的版本才能识别 其他浏览器都不执行*/
}
- 额外标签法:
在需要清除浮动的元素后面添加一个空白标签,设置类名clear,设置clear:both即可。
为什么要初始化css
考虑到浏览器的兼容问题,不同浏览器的标签默认值是不同的,为了减少页面差异会初始化css,例如:全局设置margin和padding为0
当页面渲染时遇到css和js是如何渲染的
- 根据html代码生成DOM树
- 根据css代码生成CSSOM(css对象模型)
- 整合开始渲染页面
- 遇到script标签会暂停渲染,优先执行js代码,执行完继续渲染
注意:一般把css放在head中,js放在body后面
JavaScript----------------------------------------------------------
ES6新特性
- let,const
- 模板字符串:反引号
- 解构赋值
- 箭头函数,函数参数默认值
- 扩展运算符(...)
- forEach,for...of,for...in
- 数组方法:map,reduce,includes
- promise proxy
- async
- class
- 模块化
- map集合和set集合
防抖和节流应用场景
防抖:防止抖动,避免把一次事件误认为多次。登录按钮、发短信按钮避免用户点击太快导致发送多次请求。文本编辑器实时保存、监听浏览器窗口大小时、input框实时搜索。重点:触发则清空定时器clearTimeout(timer)
节流:控制事件发生的频率。控制事件1s发生一次。例如scroll事件,每个1秒计算一次位置信息。浏览器播放事件,每个1秒计算一次进度信息。重点:开关锁timer=null
防抖:触发事件时开始计时n秒后执行回调,当n秒内事件再次被触发的话,就重新计时。
节流:在一定时间内,多次触发事件只执行一次回调。
new关键字
1.当系统检测到new关键字的时候就会在堆中开辟一块内存
2.内存中是个this对象
3.执行构造函数的函数体
4.将this对象的地址赋给我们定义的变量。
const obj1 = new student(arg)
this.$nextTick()的用法
this.$nextTick 等到下次DOM更新之后才执行回调。在修改数据之后立即使用它,然后等待DOM更新。
具体demo
进程和线程
进程:系统进行资源分配和调度的基本单位,比如微信qq就是一个进程。线程是操作系统能够进行运算调度的最小单位。
解构
解构原理:把存放在堆中的数据取出存到栈中,提高效率。
变量提升
var才有变量提升,let和const没有。
js引擎会预解析代码,遇到var声明的变量,会将声明语句提前,然后再重新执行代码。所以先用再声明会是undefined,而不会报错。
什么是回调地狱,如何解决?
回调地狱就是为了实现代码顺序执行的一种操作,它会让这个代码的可读性非常差,不好维护。
那么我们可以Promise来解决这个问题,Promise是一种异步编程的解决方案。
1.Promise构造函数接收一个函数作为参数,我们需要处理的异步任务就卸载该函数体内,该函数的两个参数是resolve,reject。异步任务执行成功时调用resolve函数返回结果,反之调用reject。
2.Promise对象的then方法用来接收处理成功时响应的数据,catch方法用来接收处理失败时相应的数据。
3.Promise的链式编程可以保证代码的执行顺序,前提是每一次在than做完处理后,一定要return一个Promise对象,这样才能在下一次then时接收到数据。
async/await
还有另外一种异步编程的解决方案就是async await,用法就是如果一个函数前面写了async,就表明这个函数是一个异步,不会阻塞后面函数的执行。然后如果你去打印这个函数的返回值时,其实是一个Promise对象。所以我们可以在这个函数后面使用.then,.catch的方法。然后await关键字只能在async定义的函数中使用,await后面一般是跟一个Promise实例对象,并且可以拿到这个实例中resolve的数据。然后必须等await后面这一步成功之后才会继续走下面的代码,这样就保证了代码的执行顺序。
移动端适配
1.视口适配:通过meta标签设置name属性为viewport
2.媒体查询适配:当屏幕宽度满足什么条件时使用什么样式
3.使用js来适配:获取屏幕的宽度然后修改样式
4.Rem适配
This指向
this指向:指向调用者,默认是指向window,但是箭头函数的this是外层上下文的this
微任务和宏任务
Js是单线程的,如果遇到异步的任务会交给浏览器处理
主线程要执行的代码=宏任务
定时器/延时器=宏任务
只有上一个宏任务执行完才会执行下一个宏任务
微任务就是promise .then .catch需要执行的内容
在事件循环队列中,微任务会插队
js用什么方式传参?
简单数据类型值传递,复杂数据类型引用传递
引用传递时重新赋值会断开引用关联
深拷贝和浅拷贝
1.浅拷贝:基本数据类型时是值传递,开了新的内存;复合数据类型时是引用传递,没有开新的内存。
2.深拷贝是再开一个内存,然后整个拷贝过去。
实现深拷贝
1. 简单版:
const newObj = JSON.parse(JSON.stringify(oldObj));
闭包
闭包其实就是我们外部可以调用到函数内部的变量,因为一般外部是不能访问到函数内的变量,但是我们可以通过将函数内的变量return出去给外部调用。
有时候我们想实现数据私有的话就可以使用闭包,如果我们定义全局变量的话容易被污染,可以把变量定义在函数内部,然后定义get方法将变量return出去,这样外部只能访问而不能修改。不过这样也导致了我们的变量一直保存在内存中,如果是一些无用变量的话就会浪费我们的内存。
1.优点:可以实现数据私有,外部可以调用内部的变量,但不能改变,防止全局污染。将变量保存在内存中不被释放,随时调用。
2.缺点:函数运行结束后不能释放内存,消耗内存。
3.闭包解决方法:函数执行完后设置函数=null。
闭包小案例:
function outer(){
let local='变量';
return function(){
console.log(local)
}
}
const fn=outer()
fn()
//闭包导致内存无法释放
//解决方法:null释放内存
fn=null
js垃圾回收机制
js中内存的分配和回收都是自动完成的,内存不使用的时候就会被垃圾回收自动回收。
垃圾回收算法:标记清除:从全局出发,不能被访问的变量就视为垃圾,进行回收。
你对js作用域链的理解?
作用域的话有全局作用域和函数作用域,当你在函数内访问一个变量的时候,会首先在自己的作用域找,如果找不到,就会往外层作用域找,直到全局。
官方:js全局有全局可执行上下文,函数调用时有函数的可执行上下文,会进入js调用栈。
每个可执行上下文都有着对外部上下文词法作用域的引用,内->外->再外,这样就形成了作用域链。
原型链的理解(构造函数+实例+原型)
为什么要在原型上添加方法?
如果一个构造函数里面有很多通用的方法,当我们new多个实例时,虽然方法都是一样,但是浪费内存。
所以如果把通用的方法放到原型上,那么每个实例都可以通过_proto_访问到。
继承
继承:就是继承一些属性和方法
比如有一个构造函数的原型有很多属性和方法,我没有,我就可以去继承过来。
我定义一个人类构造函数,有名字和年龄属性,那么我再定义一个学生构造函数,也有自己的名字和年龄属性,我再定义一个老师构造函数,也有名字和年龄属性,这样就会很麻烦。
我们可以让学生和老师去继承人类的通用属性和方法,然后自己再添加独有的属性和方法。
怎么继承?
1.原型链继承:通过改造原型链来继承
缺点:只能继承方法,属性的构造过程没有得到复用,比如this.age=age这句代码没有继承。
2. 组合式继承:两种技术的结合,原型链技术和借用构造函数(call)
ES6-class类 实现继承
判断是否为数组,不能用typeof
typeof只能判断基本数据类型。
console.log(typeof []) //输出为Object,因为万物皆对象
判断方法1:使用toString
Object.prototype.toString.call([1,2,3])) //输出:[object Array]
判断方法2:使用es6新增的Array.isArray()
isArray([1,2,3]) //true
事件循环队列
js是单线程的,遇到异步的任务会丢给浏览器执行,浏览器是多线程的。
async function fn(){
console.log(111)
}
fn()
console.log(222)
输出结果:111 222
async表示这个函数是异步的,如果没有await等于没写
async function(){
console.log(333)
const res=await 1
console.log(res)
}
fn()
console.log(222)
输出结果:333 222 1
await开始往下的内容,可以理解为写在.then的内容
async function fn(){
console.log('嘿嘿')
const res = await fn2()
console.log(res)
}
async function fn2(){
console.log('gaga')
}
fn()
console.log(222)
输出结果:嘿嘿 gaga 222 undefined
javascript的基本数据类型
undefined,null,number,string,boolean,以及es6新增的symbol
js和jquery获取标签自定义属性的方法分别是什么?
- js可以用getAttribute(),setAttribute()和dataset()获取和设置自定义属性
- jquery可以用attr()和data()方法进行获取
数组去重
使用indexOf()==-1,includes(),set集合:Array.form(new Set(arr))
Vue-----------------------------------------
什么是vue
vue是通过JavaScript封装的一套前端框架,有自己独特的API和开发模式。
vue开发的是一个单页应用(SPA),所谓单页应用开发模式就是我们不需要跳到新的页面,只需要在一个模板上加载和卸载不同的子模板来显示不同的页面。
vue的优点
- 轻量级框架
- 双向数据绑定
- 组件化
- 视图、数据和结构分离
- 虚拟DOM
- 运行速度更快
vue的组件化
所谓组件化,就是把页面拆分成多个组件,每个组件依赖的css,js,模板,图片等资源放在一起开发和维护。
虚拟DOM
虚拟dom其实就是vue使用js模拟出真实的dom,若一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地一个JS对象中,然后一次性进行更新。这样可以提高浏览器的渲染性能。
vue中的key有什么作用
key是为了给虚拟dom添加标识,也就是id。因为vue的更新机制是差异化更新,也就是通过diff算法对比新旧虚拟dom的不同来进行更新,同层兄弟元素默认是按照下标来进行对比的,如果我们添加了key,那么就是对相同key的元素来进行对比,优化了渲染性能。
如何理解Vue的响应式系统
1.视图变化了,数据会自动更新;数据变化了,视图会自动更新
2.响应式原理其实就是双向数据绑定的原理
双向数据绑定
在vue2中,通过Object.defineProperty()完成对vue实例中数据的劫持,通过对data中数据进行set的劫持监听,然后通过
观察者模式
,通知对应的节点进行数据更新。
vue3则是通过proxy来进行这个操作。但proxy的不同是它劫持的是整个对象,只要对象中的属性变化了都可以劫持到,而obj.dp只能对对象中的属性一个一个的劫持。所以vue3比vue2在性能方面提升了不少。
观察者模式
当一个对象或者数据被修改时,会自动通知依赖它的对象。
Object.definePropert和Proxy的优缺点?
Proxy:
直接监听整个对象,而非对象某个属性
可以监听数组的变化
Object.definePropert监听对象中的每一个属性
Keep-alive
Keep-alive是vue内置的一个组件,作用是可以缓存不活动的组件。比如我们组件切换之后,默认会进行销毁,如果你想不销毁上一个组件,就可以用keep-alive实现。
1.使用方法:用keep-alive标签包裹router-view标签,然后通过keep-alive的include或exclude属性去匹配需要缓存的组件。Include匹配的会被缓存,exclude匹配的不会被缓存。还可以通过路由里面的meta对象设置keepAlive属性为true进行缓存。
2.对于被缓存的组件,是不会被销毁和重新创建的,所以不会调用created这些生命周期函数,此时可以使用activated和deactivated这两个生命周期函数。
vuex
vuex是一个全局的状态管理,可以实现组件之间的数据共享。它有5个属性:
state:state里面存放数据。
mutation:存放操作state数据的方法。
action:存放异步的方法。
getters:将state里面的数据加工后给全局使用。
modules:模块化状态管理
参考链接
vue的生命周期函数
beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed
activated:被keep-alive缓存的组件中,激活时
deavtivated:被keep-alive缓存的组件中,停用时
父子组件的生命周期执行顺序
父created > 父beforeMount > 子created+mounted > 父mounted
组件通信
1.父子组件传值:props,refs,$parent
2.父传子孙:父添加provide,子添加inject
3.vuex,本地存储
vue基本指令
v-text、v-html
v-bind:简写为 :(冒号)
v-for
v-model:仅限以下标签:input select textarea
v-on:监听dom事件,简写为@;
v-show和v-if
事件修饰符:
- prevent:相当于调用了event.preventDefault()
<button @click.prevent='dianwo'></button>
- keycode:监听某个按键
<button @keydown.enter="login"></button>
<button @keydown.13="login"></button>
路由的四种跳转方式
1.router-link
2.push()
3.replace()
4.go()
参考链接
怎么去封装一个vue的自定义指令
使用vue.directive。
<script>
Vue.directive('color',{
inserted(el,bind){
el.style.background = bind.value
},
update(el,bind){
el.style.background = bind.value
}
})
</script>
<template>
<div v-color="red" ></div>
</template>
实现一个简单的双向绑定
<body>
<div id="app">
<input type="text" id="a">
<span id="b"></span>
</div>
<script type="text/javascript">
let obj={}
let val='he'
Object.defineProperty(obj,'hello',{
get:function(){
console.log('get val:'+val);
return val
},
set:function(newVal){
val=newVal
console.log('set val:'+val);
document.getElementById('a').value=val
document.getElementById('b').innerHTML=val
}
})
document.addEventListener('keyup',function(e){
obj.hello=e.target.value
})
obj.hello //调用get回调
obj.hello='hi' //调用set回调
</script>
</body>
https://blog.csdn.net/wuxy720/article/details/80151610