文章目录
1. this的了解
2. 数据类型
基本数据类型:undefined、null、number、boolean、string、symbol
复杂数据类型:object、array、function
3. ==
和===
4. undefined和null的区别
undefined是“无”的初始值,声明了但是未赋值,null是“无”的对象,也叫空指针对象
-
undefined出现的场景:
(1)、变量声明但未赋值
(2)、函数没有返回值
(3)、函数参数没有传进
(4)、对象没有赋值的属性 -
null出现的场景:
(1)、作为函数的参数传进,表示这个参数不是一个对象
(2)、作为原型链的终点
function sayHello(name = "World") {
console.log("Hello, " + name + "!");
}
sayHello("Jim"); // Hello, Jim!
ayHello(); // Hello, World!
sayHello(undefined); // Hello, World!
sayHello(null); // Hello, null!
函数参数没有传进相当于undefined可以使用默认值,函数参数为null表示不想传参同时禁用默认值。
5. 作用域和变量提升
作用域限制了变量和函数可以访问的范围,规定了怎么查找变量。分为全局作用域、函数作用域和ES6块级作用域。
作用域链:找一个变量的值,先从当前执行文上下的变量找,找不到就往父级执行文上下变量里找一直找到全局执行上下文,这种由多个执行上下文对象构成的结构就是作用域链。
变量提升:在编译阶段,会将var声明的变量提升到函数顶部,但只是提升了声明,赋值没有提升,所以可以在变量声明的位置之前使用不会报错,但值为undefined。const和let没有变量提升。
6. call,apply,bind的区别
都是改变this指向的方法
fun.call(**, arg1, arg2, arg3, ...)
fun.apply(**, [arg1, arg2, ...])
fun.bind(**, arg1, arg2, arg3, ...)()
call和apply返回的是函数结果,bind返回的是函数,需要执行。
7. 闭包的用途和缺点
用途:访问到其他函数内部的变量,属性只读,不会污染全局环境
缺点:占用内存
8. 原型链和继承
写一个继承
9. typeof和instanceof
typeof判断对象的类型typeof a
,判断参数是属于什么的实例,返回值有number、 string、 symbol、 boolean、 undefined、 object、 function
对于string/number/boolean
可以正确判断但是对于引用类型如数组,日期,正则返回的是object,而函数返回的是function,不够准确
instanceof针对引用数据类型 a instanceof b
判断a是否为b的实例
10. 深拷贝和浅拷贝
深拷贝对每一层的值都进行了拷贝,开辟了新的内存存放值,互不影响
浅拷贝拷贝的是引用地址,会相互影响
object.assign(),第一层是深拷贝,更深的层次是浅拷贝
let obj1 = { a: 0 , b: { c: 0}};
let obj2 = Object.assign({}, obj1);
obj1.a = 1
obj1.b.c = 1
console.log(obj1,obj2)
写一个深拷贝
function deepClone(obj){
let cloneObj = Array.isArray(obj)?[]:{}
for(let key in obj){
if(obj.hasOwnProperty(key)){ //使用hasOwnProperty确保属性方法在实例上
cloneObj[key] = typeof cloneObj[key] == 'object' ? deepClone(obj[key]) : obj[key]
}
}
return cloneObj
}
11. HTTPS
在HTTP的通信接口部分用TLS协议来代替,之前是http直接和tcp通信,现在是http先和TLS通信,再由TLS和TCP通信,他对传输的文件进行加密。
HTTPS四大金刚:
- 非对称加密算法(对称加密算法的秘钥)
- 对称加密算法(加密内容)
- 数字证书(防止篡改非对称加密算法的公钥)
- HASH算法(防止篡改消息)
12. 状态码302和304,502
302临时重定向
304请求的资源未修改
502请求无效
其他常见状态码
200:请求成功
202:已经接收请求,未处理完成
301:永远重定向
400:请求语法错误,服务端无法理解
403:服务端拒绝执行请求
404:请求资源无法找到
500:服务器内部错误,无法完成请求
501:服务端不支持请求
13. vue的双向绑定
14. 虚拟DOM
15. vue对数组的处理需要注意什么
vue对数组的监听:
vue的双向绑定对对象使用Object.defineProperty的setter和getter实现数据劫持对数据监听,但是对于数组是不行的,对于push,pop这样的操作对数组修改是没办法监听到的,所以vue内部重写数组的原型方法,最后返回一个新的数组覆盖掉原来的数组,实现了一组观察数组的变异方法,例如:push(),pop(),shift()等,从而实现监听。
vue不能检测的数组变动
- 利用索引直接设置一个值,例如
arr[index]=newValue
- 修改数组的长度:
arr.length = newLength
解决方法:
splice(index, 1, newValue)
/vm.$set(arr, index, newValue)
arr.splice(newLength)
key的作用
解决v-for就地复用原则带来副作用的方法,而且在比较虚拟DOM diff算法的时候,更加准确,更加快速,根据key值生成map对象,在diff算法头尾的四种比较都不符合的时候,不再需要遍历,直接用map映射找到元素,速度更加快
16. vue-router两种模式的区别
路由的本质是监听url变化然后匹配路由规则,显示相应的页面并且无需刷新。
实现方式有history
和hash
两种模式
- hash模式:利用url后面的#,#后面的hash修改不会刷新页面也不会发送http请求,可以通过
hashchange
监听ur的变化进行跳转页面。
- history模式:利用了html5的history api的
pushState
和replaceState
方法,pushState把页面的状态保存在一个状态对象中,页面的url再次变回这个url的时候可以通过event.state
取到这个state对象从而对页面还原。
缺点:要在后台进行一些配置,前端的url必须要和实际向后台发送请求的url地址一致,不然就会返回找不到资源,返回404。
- vue-router的传参
router.push
传参
(1) 命名路由
传递:this.$router.push({ name: 'path', params: { id: 123 }})
接收:this.$route.params.id
(2) 查询参数:路由地址后面带上参数
传递:this.$router.push({ path:'path', query: { id: 123 }})
接收:this.$route.query.id
<router-link>
(1) 命名路由
<router-link :to="{ name: 'news', params: { id: 123 }}">
(2) 查询参数
<router-link :to="{ path: '/news', query: { id: 123 }}">
17. 两栏布局(左边240px,右边自适应)
18. rem和em
rem和em是相对长度单位
rem转化像素大小取决于根元素的字体大小,即根元素font-size * rem
em转化像素单位是取决于本身使用的字体大小,此字体大小受父元素继承过来的字体大小影响。
- 哪个的兼容性好?
rem提供的是一致的尺寸而不是继承,可以通过一个根元素来影响网站上每一处使用rem的元素大小,计算起来更清晰。
19. 算法:判断B是否是A的子数组
题目:两个数组A,B,都是升序的,判断B是否是A的子数组
var arr1 = [1,2,3,5,5]
var arr2 = [1,2,5,5,5]
function fun(A, B){
for(let i=0; i<B.length; i++){
if(A.includes(B[i])){
var index = A.indexOf(B[i])
var num1 = 1
for(let j=index+1; ;j++){
if(A[j] === B[i]){
num1++
}else{
break
}
}
var num2 = 1
for(let j=i+1; ;j++){
if(B[j]===B[i]){
i = j
num2++
}else{
break
}
}
if(num2>num1){
return false
}
} else {
return false
}
}
return true
}
console.log(fun(arr1, arr2))