1.防抖与节流
防抖:在同一段时间内,如果指定的函数不断的触发,只会执行最后一次,也就是说,执行函数时,时间会被重新计算。例如:指定了1000ms的防抖函数,只要你在1000ms的时间间隔内一直点击,无论过去多长时间,只会在最后一次点击的时候生效。
const delay = (function () {
let timer = 0
return function (callback, ms) {
clearTimeout(timer)
timer = setTimeout(callback, ms)
}
})()
节流:在同一段时间内,只触发1次函数,可以理解为无论执行了几次函数,都只会在每xxx时间内执行一次。例如:指定了1000ms的节流函数,2000ms内点击10次按钮会在第1000ms和第2000ms执行2次点击事件。
function throttle(fn,wait) {
let timeout=null;
return function () {
let that=this;
let args=arguments;
if (!timeout) {
timeout=setTimeout(()=>{
timeout=null;
fn.apply(that,args);
},wait)
}
}
}
2.为什么CSS外链需要放头部?
因为页面整个展示都会通过html的解析与渲染过程。css外链无论放哪一个位置都不会影响html的解析,但是影响html的渲染,如果css放头部,则css的下载和解析是可以和html的解析同步完成,如果放到了尾部,则会优先解析出html再去通过css渲染页面,页面就会出现先出现一个没有样式的页面,再完成解析造成闪动的情况,特别是网络不好的情况下。
3.为什么script建议放尾部
页面的解析执行过程是从上到下的,当解析到script的时候,就会立刻下载执行,中断html的解析过程,如果script响应时间很长,会造成页面长时间无响应,影响体验,也就是“阻塞效应”。
对于这种情况,可以进行一些额外的设置,来改变这种模式:
1.defer属性:给js脚本添加defer属性,会让脚本的加载与文档的解析同步,等页面解析完成后,再去执行脚本,但是兼容性不好。
2.async属性:也就是异步属性,和defer差不多的是同样是一起加载,但是如果页面慢与脚本解析完成的话,同样会引起阻塞的情况。
3.动态引入:可以监听页面的加载完成事件,页面加载完成后,动态创建script进行引入。
4.let和const的区别
const是常量,不允许修改,const为对象时,可以修改对象内部值的数据
let是块作用域,只有当前模块上才能访问,必须要声明后才能使用,而且不允许重新定义
var是函数作用域,可以先使用再声明,比如再for循环内使用,for循环外是可以访问的,而且可以重新定义
5.vue双向绑定原理
vue双向绑定是通过数据劫持、组合、发布订阅模式的方式来实现的,核心是通过Object.defineProperty()的get和set来进行数据劫持
6.html5的新特性
1.新增header,footer,nav,section,article,main等语义化标签
2.增强型表单,email,url等字段,placeholder和required等属性
3.新增audio和video标签
4.新增canvas绘图,svg绘图等
5.新增地图定位getCurrentPosition
7.Web Storage
1.localStorage:最大5M,在浏览器中永久保存,小程序中有时效性
2.cookie:最大支持4k,可以设置失效时间,如果不设置的话,关闭浏览失效,请求的时候,会包含在http请求中,产生额外的流量
3.sessionStorage:最大5M,当前会话网页下有效,关闭网页或浏览器失效
8.ES5和ES6
1.新增了const常量和let变量
2.新增了箭头函数()=>
3.es5需要使用require引入包,es6可以使用import引入
4.函数变量默认值设置function(x,y=1)
5.Promises链式异步操作对象
6.对象的操作,如合并对象...
9.Html语义化
1.利于SEO
2.在没有css的情况下能够更好的呈现页面结构
3.方便浏览器解析和一些很低版本的浏览器解读
4.可读性更好
5.alt title等用户体验性提升
10.relative、absolute、fixed、sticky
1.relative 相对定位于原来自己的位置,会占据原有元素空间,脱离文档流
2.absolute 绝对定位于距离自己最近的祖元素或document,完全从文档流删除,不会占用原有空间
3.fixed *固定定位于浏览器窗口
4.sticky 黏性定位当元素未超出目标区域时,相当于relative,当超出时,相当于fixed
11.判断数据类型的方法
1.typeof: typeof a==='function'
2.instanceof [] instanceof Array
12.cookies、session、localstorage
1.cookies:cookie一般是服务器发给客户端的信息,以文本的形式存在,每次请求都会在http请求同中带上该信息,还具有路径的概念,可以存在某个路径下
生命周期:如果不设置过期时间,会随浏览器关闭而关闭(会话cookie),如果设置了过期时间,则会保存到内存里,关闭浏览器不会消失,除非时间到期或手动清除
最大限制:4kb,一般不超过20个
2.session:仅在本地保存,不会发送给服务器
生命周期:会话级,浏览器关闭或网站关闭后,就会清除
最大限制:5M左右
3.localstorage:仅在本地保存,不会发送给服务器
生命周期:持久化保存在本地硬盘里,但是小程序里会有限制
最大限制:5M左右,在uniapp的打包的app里localstorage里无限制
13.Vue组件通信的方式
1.props:父组件向子组件传递数据,子组件还可以通过watch监听
2.$emit和$on可以实现任意组件之间的通信
3.全局事件总线
4.vuex
14.Vuex以及属性
全局状态管理,state上的状态改变时,相应的地方也会改变
1.state:基本数据(通过mapState把state和getters映射到当前组件的计算属性computed上)
2.getters:从基本数据派生的数据(getter可以对state计算操作,就是store的计算属性)
3.mutation:提交更改数据的方法,同步(mutation是进行提交而不是改变状态)
4.action:类似于一个装饰器,可以包裹mutation,使之异步
5.module:模块化vuex,在中大型应用中允许将store分割成不同模块
使用场景:在中大型应用中,使用vuex在组件外部管理状态,利于维护:用户信息存放,一处修改n处改变,订单状态刷新,优惠券,收货地址,购物车数量等更新
15.pop、push、shift、unshift
push() 方法可以在数组的末属添加一个或多个元素
shift() 方法把数组中的第一个元素删除
unshift() 方法可以在数组的前端添加一个或多个元素
pop() 方法把数组中的最后一个元素删除
通过pop和push可以实现类似栈的效果
16.强类型转换和隐式转换
强类型转换:String,Date,JSON.stringify、Number、parseInt之类的
隐式转换:
var a='1'
var b=0
console.log(+a) //输出 number类型1
console.log(b+'')//输出 string0
17.Vue双向绑定原理
vue数据的双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。其核心就是通过Object.defineProperty()方法设置set和get函数来实现数据的劫持,在数据变化时发布消息给订阅者,触发相应的监听回调。也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;
18.虚拟dom
模板 ==> 渲染函数 ==> 虚拟DOM树 ==> 真实DOM
虚拟DOM其实就是用一个原生的JS对象去描述一个DOM节点,实际上它只是对真实 DOM 的一层抽象。最终可以通过一系列操作使这棵树映射到真实环境上。
相当于在js与DOM之间做了一个缓存,利用patch(diff算法)对比新旧虚拟DOM记录到一个对象中按需更新, 最后创建真实的DOM
19.JS原型链
原型:被用于复制现有实例来生成新实例的函数
构造函数:用new来调用,就是为了创建一个自定义类
实例:是类在实例化之后一个一个具体的对象
原型链:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么假如我们让原型对象等于另一个类型的实例,结果会怎样?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条。
prototype
js中每一个函数都有prototype属性,这个属性指向函数的原型对象,每一个由原型对象派生的子对象,都有相同的属性。子对象就叫构造函数,从实例原型中获取相同的属性。所有创建在同一原型的prototype,无论怎么实例化,最终指向的原型都是同一个,减少了内存开销。
function Test(_arg){
this.arg=_arg
}
Test.prototype.name='小明'
Test.prototype.fn1=function(){}
var t1=new Test(29)
var t2=new Test(20)
console.log(t1.name)//小明
console.log(t2.name)//小明
Proto
它是每一个子对象(除null外)都会有的一个新的属性,实例化(new)的时候,指向该对象的原型,说白了指向的是该构造函数的引用地址
console.log(t1.__proto__===Test.prototype)//true
构造函数 constructor
每个原型都有一个constructor属性,指向该关联的构造函数。
console.log(Test==Test.prototype.constructor)//true
-所有函数的proto都是指向Function的prototype
-构造函数new出来的对象proto指向构造函数的prototype
-非构造函数实例化出的对象或者对象的prototype的proto指向Object的prototype
-Object的prototype指向null
Comments NOTHING