1.var和let
var的三个问题
- 无块级作用域
- 变量覆盖
- 声明提前
2.深拷贝和浅拷贝
数组和对象的赋值都叫浅拷贝
解构赋值针对一维数组和对象可以看作是深拷贝,多维的就是浅拷贝
JOSN.parse(JOSN.stringify())//function不能用
3.this指向
指向上一个调用者
箭头函数没有作用域,没有this
call, apply( )改变之后,并且执行一次
bind( )不调用 只改变this指向
apply=> [] call=>{}
4.为什么要有闭包
1.避免变量被污染
2.私有化
3.保存变量,常驻内存
4.闭包的应用场景=>防抖,节流,库的封装
5.事件委托
利用事件冒泡,只指定一个事件处理程序,就可以管理一系列事件
6.区别数组和对象的方法
Object.prototype.toString.call()
instanceof
constructor
7.typeof null的结果是什么
Object
8.如何让0.1+0.2===0.3
function numberepsilon(arg1,arg2){
return Math.abs(arg1-arg2)<Number.EPSILON
}
console.log(0.1+0.2,0.3)
9.typeof NaN的结果是什么
number 执行数学运算没有成功,失败后返回的结果
10.**===与==
==对比双方类型不一样,就会进行类型转换
===必须一摸一样
11.什么是js中的包装类型
js中,基本类型是没有属性和方法的,为了便于操作在调用基本类型的属性或方法时js会在后台隐式转换成对象
const a='abc'
a.length //String('abc').length
12.+ - * /
+的左右两边至少一个string类型变量时,两边的变量都会转换成字符串;其他情况下两边的变量都会被转换成数字
除了加法的运算符,只要其中一方是数字,那么另一方就会被转为数字
13.提取高嵌套的对象里的指定属性
const school = {
classes: {
stu: {
name: 'Bob',
age: 24,
}
}
}
//常规方法
const {classes} = school
const {stu} = classes
const {name} = stu
//简洁方法
const {classes: {stu: {name}}}=school
14.数组有哪些原生方法
数组尾部操作的方法:pop( )和push( )
数组首部操作的方法 shift() 和 unshift()
数组连接的方法 concat() ,返回的是拼接好的数组,不影响原数组。
数组截取办法 slice(),用于截取数组中的一部分返回,不影响原数组
15.arguments
argumens转化成数组
const arrArgs=[...arguments]
16.防抖和节流
防抖:定时器先清除,然后再创建定时器
节流:先判断是否存在定时器,然后创建完定时器后在内部清除
17.解构
如果想创建的变量名和对象的属性名不一致,可以这么写
const {a:a1}=obj
18.includes
if(type == 1 ||
type == 2 ||
type == 3 ||
type == 4 ||
){
//..
}
//改进后
const condition=[1,2,3,4]
if(condition.includes(type)){
//..
}
19.for···in和for···of
for···in循环出的是key,for···of循环出的是value
ES6以后
for···in可以用Object.keys
for···of可以用Object.values
20.数组扁平化
const deps = {
'采购部':[1,2,3],
'人事部':[5,8,12],
'行政部':[5,14,79],
'运输部':[3,64,105],
}
let member = Object.values(deps).flat(Infinity);//flat 纬度;infinity无限
21.可选链操作符
const name=obj?.name//const name=obj&&obj.name