-
路由守卫
分为全局路由守卫和 路由独享的守卫
全局路由守卫 使用 router.beforeEach((to, from, next)=>{})
路由独享守卫 使用 router.beforeEnter((to, from, next)=>{}) -
什么是路由?
路由就是URL到函数的映射,路由的本质是监听URL的变化,然后匹配路由规则,显示相应的页面 -
Router和Route
每一条route是一条路由, 其中包括当前路径和映射的URL。
router类似一个容器,立main包裹着一条条的route -
forEach forin forof 三折的对比
forEach用来循环数组,可以直接取到元素,同时也能取到索引值,但不能用 break 终止循环,没有返回值 不能return
forin 一般循环遍历都是对象的属性,遍历对象本身的所有可枚举属性,以及从构造函数原型中继承的属性key 会变成字符串类型
forof 是ES6 引入的标准,一般情况下用于遍历数组,可以遍历数组内的值,和索引无关 -
怎样设置cookie的有效时间
Max-Age 指定从现在开始 Cookie 存在的秒数, 秒数过完则 cookie过期 -
let 和 const
let 不能重复声明变量, var 可以重复声明变量
let 声明的变量不存在var的变量提升问题
let 是声明提升
const 主要用于声明常量 -
基本数据类型和引用数据类型的区别
基本数据类型是按值访问的,可以直接操作保存在变量中的实际值(保存在栈中)
引用数据类型是保存在堆内存数据中的对象,不可以直接操作堆内存空间中的位置和堆内存空间,只能操作对象在堆内存中的引用地址
总结:
a、声明变量时不同的内存分配
原始值 存储在栈中,直接访问存储在变量访问的位置
引用值 存储在堆中的对象,存储在变量处的值是一个指针,指向存储对象的内存指针
b、不同的内存分配也带来了不同访问机制
原始值是可以直接访问的
引用值是按引用访问
c、复制变量时的不同
原始值 复制时完全独立的
引用值 把内存地址复制给新变量 -
解构赋值
针对一维数组是深拷贝,针对多维是浅拷贝 -
箭头函数和普通函数的区别
箭头函数的this 是静态的
箭头函数内的指针指向上层对象,始终指向函数声明时所在作用域下的this的值,无法被call改变
普通函数的this指向调用其函数的对象
箭头函数不能作为构造函数实例化对象
箭头函数能使用arguments变量。但可以使用…rest箭头函数的简写 -
页面防流和节抖
防抖 在第一次出发事件时,不立刻执行函数而是给出一个期限值 比如 200ms
效果 如果短时间内大量出触发同一事件,只会执行一次函数
setTimeout 借助闭包实现
节流
如果在短时间内大量触发同一事件,那么在函数执行之后,该函数在指定的时间期限内不在工作,等待过了这段时间才从新生效
settimeout。加上一个状态位来实现 -
深浅拷贝
浅拷贝 object.assign()
深拷贝 JSON.parse(JSON(stringify(obj))
浅拷贝只会复制指向某个对象的指针而不是对象本身 新旧对象共享同一内存
深拷贝创建出一个新的对象 修改不会改变原数组 -
一句话解释什么叫原型链
遍历一个实例的属性时,先遍历实例对象上的属性,在遍历他的原型对象 一直遍历到object -
new运算符具体做了什么
首先创建实例对象
this变量引用该对象,同时还继承了构造函数的原型
其次属性和方法被加入到this引用的对象中
并且新创建的对象由this所引用,最后隐式的返回this -
宏任务和 微任务
当前调用栈中执行的任务称为宏任务,(setTImeout js 代码)
当前宏任务执行完,在下一个宏任务开始执行之前需要执行的任务(promise)
宏任务放在 callback中,由事件触发线程维护
微任务的事件放在微任务队列中,由js引型线程维护 -
vue响应式数据原理
响应式 当数据改变后,Vue会通知使用该数据的代码
比如说 试图渲染了一个数据
当数据发生改变后 视图会响应式的自动更新
Vue式通过 object.defineProperty() 来更新定义data中的所有属性 -
输出执行结果
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2() {
console.log("async2");
}
console.log("script start");
setTimeout(function () {
console.log("setTimeout");
}, 0);
async1();
new Promise(function (resolve) {
console.log("promise1");
resolve();
}).then(function () {
console.log("promise2");
});
console.log("script end");
- 请编写函数,将data数组中所有对象按照value从小到大排列。
var data = [{
name: "uc",
value: 5
}, {
name: "amap",
value: 2
}, {
name: "ali",
value: 3
}.....
]
function sortFn( parameter ){
return function(a,b){
var value1 = a[parameter]
var value2 = b[parameter]
return value1-value2;
}
}
var result = data.sort(sortFn('value'));
consele.log(result);
或者:
var result = data.sort((a, b) => a.value- b.value)
consele.log(result);
请编写函数,上一题data数组中查找name为amap的数据。
var select = function(data, param){
for (let i = 0; i < data.length; i++) {
const ele = data[i];
if(ele.name = param){
return ele;
}
}
}
console.log(select(data, 'amap'));
或者
console.log(data.find(ele => {
return ele.name === 'amap'
}))
请编写函数,将16题中data数组转为以name值为key的对象。转换后的样例如下
{
amap:{
name:"amap",
value:2
},
uc:{
name:"uc",
value:5
},
}
- 如何让子元素在父元素中垂直、水平居中?
var trans = function (data){
var obj = {}
for (let i = 0; i < data.length; i++) {
let ele = data[i];
var keyName = ele.name;
obj[keyName] = ele;
}
return obj;
}
console.log(trans(data));
或者使用es6写法:
const todo = arr => {
let obj = {};
let KEYS = Array.from(arr, ({ is }) => is);
KEYS = [...new Set(KEYS)];
KEYS.forEach(i => {
obj[`is${i}`] = arr.filter(item => item.is === i)
})
return obj
}
console.log(todo(data))
方法1 :
.parent {
width: 500px;
height: 500px;
border: 1px solid #000;
position: relative;
}
.child {
width: 100px;
height: 100px;
border: 1px solid #999;
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;
}
方法2
.parent {
width: 500px;
height: 500px;
border: 1px solid #000;
position: relative;
}
.child {
width: 100px;
height: 100px;
border: 1px solid #999;
position: absolute;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
方法3
.parent {
width: 500px;
height: 500px;
border: 1px solid #000;
display: flex;
justify-content: center;
align-items: center;
}
.child {
width: 100px;
height: 100px;
border: 1px solid #999;
}



