## √ 数据类型判断
数据类型判断可以通过 typeof,instanceof
typeof 返回的是一个表示数据类型的字符串
instanceof 是用来判断 A 是否为 B 的实例,用来测试一个对象在原型链中是否存在构造函数的 prototype 属性,不能检测 null 和 undefined
object.prototype.string.call()
## √call,apply,bind 的区别
他们三个主要都是用来改变 this 指向的
call 和 apply 在改变 this 指向的时候调用了函数,但是 bind 没有调用,而是生成了一个新的函数,call 和 bind 是逐个进行传参,apply 是通过数组的方式进行传参
## √this 指向问题
1.直接调用的时候,this 指的是 window
2.在 obj.函数,this 指向的是谁就调用了谁的函数
3.在构造函数里面,this 指向的是当前类的实例
4.箭头函数没有自己的 this 指向,看看是否有外层函数,如果有外层函数,外层函数的 this 指向就是箭头函数的 this 指向,如果没有 this 指向 window
5.call,appiy,bind 指向的是第一个参数
## √ 原型,构造函数,实例
原型:他是一个简单的对象,用于实现属性的继承,每个 js 对象都有一个--proto--的属性指向该对象的原型
构造函数:可以通过 new 来实现一个对象的函数,我们可以把对象中的一些公共的属性和方法抽离出来,然后封装到这个函数里面
实例:通过构造函数和 new 出来的的对象,通过 proto 指向原型,通过 constructor 指向构造函数
**new 在执行时会做四件事情:**
1.在内存中创建一个新的空对象
2.让 this 指向这个新的对象
3.执行构造函数里面的代码,给这个新的对象添加属性和方法
4.返回这个新的对象(所以构造函数里面不需要 return)
## √ 原型链
当查找对象的属性的时候,沿着--proto--往自己的原型上查找,找到则输出,不存在的时候则沿着原型链一步一步继续往上查找,直到最顶端 object.prototype,如果还找不到返回 null
## √ 闭包
闭包其实就是函数套函数,一个函数有权访问另一个函数里面的变量,可以将变量长期保存在内存中,生命周期较长,但是闭包会造成内存泄漏,影响性能问题
## √ 浅拷贝与深拷贝
浅拷贝只是复制对象的引用地址,不是复制对象本身,修改的时候原对象也会受到影响
实现方法:赋值,object.assign,slice,concat
深拷贝就是在拷贝数据的时候将引用结构全部拷贝一遍,两个数据结构相互独立互不影响,改变数据的时候不会改变原数据
实现方法:JSON.parse(JSON.stringify()),递归,loadsh
JSON.parse(JSON.stringify())的缺点是如果里面有函数的话会丢失
## \*\*防抖节流
防抖节流都是优化方式
**防抖**:将多次高频操作优化只在最后一次执行 ,(一般用于用户在输入框很频繁的输入信息时候用)
1. 创建一个函数
2. 函数内定义一个 timer 为 null
3. 借助闭包函数内返回一个函数
4. 在内部调用的函数中判断如果 timer 有值就清除定时器,清除之后重新设置 setTimeout,给定时器传入需要防抖函数与时间,
5.在内部调用的函数中判断如果 timer 没有值,直接设置 timer 为 setTimeout,给定时器传入需要防抖的函数与时间
**节流**:每隔一段时间执行一次,降低频率,(一般用于滚动条事件,拖拽的时候)
① 创建一个节流函数
② 函数内定义一个值为布尔的开关,开关为 true 。
③ 借助闭包函数内返回一个函数
④ 在内部调用的函数做判断,如果定义的布尔值开关为 false 直接返回 false,否则开关为 false,之后设置 setTimeout,定时器中传入一个需要节流的函数并吧开关设置为 true
## for in 和 object.keys 的区别?
**for in** :遍历对象可枚举属性,包括自身属性,以及继承自原型的属性
**Object.keys()**:返回一个数组,数组值为对象自有的属性,不会包括继承原型的属性