js
js基本类型
基本类型:字符串(string),数字(number),布尔型(boolean),空(null),未定义(underfined),symbol
引用数据类型:对象Object,数组Array,函数Function
注:symbol是es6引用了一种新的原始数据类型,表示独一无二的值。
数组的方法
unshift():数组头部添加内容
push():数组尾部添加内容,返回新的长度
pop():数组尾部删除内容
shift():数组头部删除内容
sort():数组元素进行排序(ascII码排序)
join():把数组已有元素放入一个字符串,元素通过指定的分隔符进行分割
reverse():颠倒数组中元素的顺序
slice():从某个已有数组返回选定的元素
valueOf():返回对象的原始值
splice(index,length,【item】):删除元素,并向数组添加一个新元素
toSource():返回该对象的源代码
toString ():把数组转换为字符串并返回结果
toLocaleString():把数组转换为本地数组,并返回结果
数组去重
1,es6新增数据类型Set,Set的最大一个特点就是数据不重复
let arr=[1,2,3,1]
function newArrFn(arr){
//new Set方法,返回是一个类数组,需要结合Array.from()转换为真实数组
return (Array.from(new Set(arr)))
}
console.log(newArrFn(arr)) //[1,2,3]
2,利用includes检查新数组是否包含原数组的每一项,如果不包含,就push进去
let arr=[1,2,3,1]
function newArrFn(arr){
let newArr = []
for(let i = 0;i < arr.length;i++){
newArr.includes(arr[i]) ? newArr : newArr.push(arr[i])
}
return newArr
console.log(newArrFn(arr)) //[1,2,3]
this指向
改变this指向: call, apply, bind. call和apply调用函数,bind不会调用.
webpack
webpack基本功能和工作原理
- 代码转换: typescript编译成js, scss编译成css等
- 文件优化: 压缩js, css, html代码, 压缩合并图片等
- 代码分割: 提取多个页面的公共代码, 提取首屏不需要执行部分的代码, 让其异步加载
- 模块合并: 某个模块引用其他的模块和文件, 需要构建功能, 把模块合并成一个文件
- 热更新: 检讨本地原代码变化, 自动构建, 更新内容
forEach和map的区别
forEach: 没有返回值
- 参数: value数组的当前项, index当前项的索引, array原始数组
- 数组中有几项, 那么传递进去的匿名回调函数就需要执行几次
- 理论上这个方法是没有返回值的, 只是遍历数组的每一项, 不对原数组进行修改, 但是可以自己通过数组的索引来修改原来的数组
map: 有返回值,可以return出来
- 参数: value数组的当前项, index当前项的索引, array原始数组
- 区别: map的回调函数中支持return返回值, return的是什么, 相当于把数组中的一项变为什么(并不影响原来的数组,只是把原数组克隆了一份, 把克隆这一份的数组中的对应项改变了)
防抖和节流
防抖和节流函数是一种最常用的, 高频触发优化方式, 能对性能有较大的帮助
防抖(debounce): 将多次高频操作优化为只在最后一次执行,通常使用的场景是: 用户输入,只需再输入完成后做一次输入校验即可.
- 防抖: n秒后再执行该事件, 若在n秒内重复触发,则重新计时
节流(throttle): 每隔一段时间后执行一次,也就是降低频率,将 高频操作优化为低频操作,通常使用场景: 滚动条事件,或者resize事件,通常每隔100-500ms执行一次即可.
- 节流: n秒内只执行一次,若在n秒内重复触发,只有一次生效.
原型和原型链
原型(prototype): 一个简单的对象,用于实现对象的属性继承. 可以简单的理解原型的爹. 每个JavaScript对象都包含一个--proto--(非标准)指向它爹(该对象的原型), 可obj.--proto--进行访问.
原型链: 简单理解就是原型组成的链, 对象的--proto--是它的原型, 而原型也是一个对象,也有一个--proto--属性,而原型的--proto--又是原型的原型, 就这样可以一直通过--proto--向上找,这就是原型链, 当向上找找到Object.prototype原型链的顶端, 所有对象从它继承了包括toString等等方法和属性. js就是通过这个链条来实现的继承
按照js引擎的分析方式, 在访问一个实例的属性或方法的时候,先在实例本身中找, 如果没找到就去它的原型中找, 还没找到就再往上找,直到找到.
闭包
闭包指有权访问另一个函数作用域中的变量的函数
- 作用
- 使用闭包可以访问函数中的变量
- 可以使变量长期保存在内存中,生命周期比较长
- 缺点
- 闭包不能滥用,会导致内存泄露,影响网页性能
- 应用场景
- 函数作为参数传递
- 函数作为返回值
性能优化
从哪些点做性能优化
- 加载
- 减少http请求(精灵图,文件的合并)
- 减少文件大小(资源压缩,图片压缩,代码压缩)
- CDN(第三方库,大文件,大图)
- SSR服务端渲染,预渲染
- 懒加载
- 分包
- 减少dom操作,避免回流,文档碎片
vue
为什么选择vue.js
文档清晰,生态完备,双向绑定机制简单好用
vue响应式原理
数据发生变化时,视图会重新渲染,匹配更新为最新的值. objcet.defineProperty为对象中的每一个属性设置get和set方法,每个声明的属性都有依赖的subs,当页面用到某个属性时,触发object.defineProperty-get函数,页面的watcher就会放到属性的subs中,数据变化时通知更新,触发object.defineProperty-set函数. 数据遍历自己的依赖subs, 通知watcher视图更新
vue生命周期
- 创建
- beforeCreate阶段, vue实例的挂载元素$el和数据对象data都为underfined,还未初始化(啥也没有)
- created阶段, vue实例的对象data(有data,没$el)
- 载入
- beforeMount阶段,vue实例的$el的data都初始化,但还是挂载之前为虚伪的dom节点,data.message还未替换(有data,没$el)
- mounted阶段,vue实例挂载完成,data.message成功渲染(有data,有$el)
- 更新
- 当data变化时,会触发beforeUpdate和updated方法
- 销毁
- beforeDestroy在执行destory方法后, 对data的改变不会触发周期函数,说明此时vue实例已经解除了事件监听和dom的绑定以及释放定时器,但是dom结构依然存在
- keep-alive
- 有keep-alive第一次执行前4个生命周期+activated
- 第二次第三次第n次进入时只执行activated
keep-alive
vue内置组件,使包含的组件保留状态,或避免重新渲染,也就是组件缓存,有了它vue多了两个生命周期activated, deactivated
vue双向绑定原理
vue是利用数据劫持和发布订阅模式来实现双向绑定, 数据劫持利用object.defineProperty()方法,给数据对象每个属性添加了set和get,在数据写入和读写时触发自定义方法
vue传值
父传子: 子组件在props中创建一个属性,用来接收父组件传过来的值; 在父组件中注册子组件;在子组件标签中添加子组件props中创建的属性,把需要的值赋给该属性
子传父: 子组件中需要某种方式(如点击事件)的方法来触发一个自定义事件,将需要传的值作为$emit的第二个参数,该值将作为实参传给响应事件的方法,在父组件中注册子组件并在子组件标签上绑定自定义事件的监听.
平行组件: $emit推送,$on接受
兄弟组件通信
借助父组件,让兄弟组件联动,子组件a将值传递给父组件,父组件再将值传递给子组件b
- 子组件a传值给父组件,通过$emit将e.terget.innerText传递给父组件
- 父组件接收子组件a的传值,并将值保存到自己的data中,并取名letter(letter:字母)
- 父组件将letter传递给子组件b,子组件b通过props接收该值
注意:子组件b监听到letter值的变化后作出反应. 用watch对象来监听,还可以用$bus总线传值
vuex是什么,那些场景会用到
vuex是单向数据流
vuex是一个专门为vue.js应用程序开发的状态管理模式,我们大概可以理解为vuex是一个公共组件库,你可以在所有组件里面去使用
修改场景:单页面应用中,组件之间的状态,音乐播放,登录状态,加入购物车
vuex为状态管理,它集中储存管理应用的所有组件的状态,可以理解为一个全局仓库
vueRouter是路由(spa)单页面应用的方式
vuex持久化存储
- 使用localStorage
- 使用插件
vuex的优势,主要解决问题
vuex优势:
- 减少了非父子组件的消息传递(数据存放在state中)
- 减少了ajax请求次数,有些情景可以直接从内存中的state获取
主要解决问题
用来管理全局的组件状态,比如有很多个组件都会修改同一个数据,同时这个数据又要在多个组件上同时维护,这时候用vuex来统一管理这些组件的状态,会让逻辑更清晰,更方便维护
路由懒加载如何实现
路由懒加载是性能优化的一种手段,在编写代码时可以使用import引入路由组件,使用懒加载的路由在打包时单独出来成一个js文件,可以使用webpackChunkNume自定义包名,在项目上线后,懒加载的js文件不会在第一时间加载,而在访问到对应的路由,才会动态创建script标签去加载这个js文件
v-model和v-bind区别
v-model: 双向绑定,改变输入值,有界数据被改变,反之亦然
v-bind: 单项绑定,绑定一个value属性
v-show和v-if的区别
v-if会让条件块内元素或组件适当地被销毁和重建
v-show的元素或组件首次加载就被渲染,所以频繁切换使用v-show, 不常切换则使用v-if
v-for和v-if的优先级
v-for优先级高于v-if
小程序
小程序导入外联样式
- @import '导入的相对路径'
小程序登录
- wx.login获取临时登录凭证code
- 发生code给后端,后端通过code,appid,appsecret调用微信接口,返回openid和session-key
- 后端通过openid和session-key生成token(身份令牌)返回给前端
- 前端把后端返回的token缓存起来
unionid: 用户的唯一性
提高小程序应用速度
- 提高页面加载速度
- 用户行为预测
- 减少默认data大小
- 组件化方案
小程序双向绑定和vue的区别
大体相同,但小程序之间this.data属性不可以同步到视图,必须调用this.setData()方法
小程序生命周期
onLaunch()用户首次打开小程序触发(全局只触发一次)-->onShow()小程序初始化完成后触发,一般用来发送数据请求-->onLoad()页面加载时触发,一般用来发生数据请求-->onShow()-->onReady()页面初次渲染完成时触发,只调用一次,代表视图层可进行交互
onHode():页面隐藏/切入后台时触发,如底部tab栏切换到其他页面或小程序切入后台等
onUnload():页面卸载时触发,如redirectTo或navgateBack到其他页面
浏览器存储Cookie,localStorage,SessionStorage,区别
Cookie:
- 由服务器生成,可设置失效时间,默认关闭浏览器失效
- 大小限制4kb左右
- 每次都会携带在http头,使用cookie保存过多数据,会带来性能问题
- 需要自己封装,原生不好用
localStorage:
- 除非被清除,否则永久保存
- 一般为5Mb
- 仅在浏览器中保存,不参与和服务器通信
- 可接受原生,亦可接受再次封装,对object和array有更好支持
sessionStorage:
- 仅在当前会话生效,关闭页面和浏览器后被清除
- 一般为5Mb
- 仅在浏览器中保存,不参与和服务器通信
- 可接受原生,亦可接受再次封装,对object和array有更好支持