1、内置类型:
string number null undefined boolean symbol
注意:数字类型的精度问题,NaN属于number类型,但是自身不相等
复杂类型:object:复制时注意深浅拷贝的问题
2、typeof:显示变量的数据类型
注意:除null外都可正常显示,对object使用时只有function会显示微function
3、类型转换:
转boolean为false有7个:null undefined false '' 0 -0 NaN
注意基本类型:转换时会先调valueOf,再调toString,并且可以重写这两个方法
如何使(a==1&&a==2)返回true?
let a = {
value:0,
valueOf(){
return this.value += 1;
}}
如何使(a===1&&a===2)返回true?
var value = 0;
Object.defineProperty(window,'a',function(){
return this.value +=1;
})
4、原型:prototype
每个函数都有prototype属性,除bind外,该属性指向原型。
每个对象多有_proto_属性,指向创造了该对象的构造函数的原型,指向[[prototype]]这个内部属性,内部属性访问不到,所以用_proto_.
对象通过_proto_来寻找不属于该对象的属性,将对象连接起来,组成原型链。
5、new
1.新生成一个对象
2.绑定this
3.绑定原型
4.return新对象
实例的优先级大于构造函数的优先级
6、instanceof
用来判断原型链中能不能找到类型的原型
7、this
指向调用当前函数的对象,如果没有就指向window
箭头函数没有this
匿名函数this一般指向window
8、闭包
定义1:可以访问另一个函数作用域的函数
定义2:保证作用域中的变量不被回收
主要应用在同级函数
经典问题是循环输出12345的问题
解决方案:1.闭包 2.定时器的第三个参数 3.var-let 4.循环放外边
9、深浅拷贝
两个变量引用同一个变量,修改的时候会互相影响
浅拷贝:使用object.assign() 或者展开运算符...
深拷贝:当对象里还有对象,上述浅拷贝方法不管用,可使用JSON.parse(JSON.stringify(obg))
该方法局限性:会忽略undefined 会忽略symbol 不能序列化函数 不能解决循环引用的对象
可使用lodash深拷贝函数
10、防抖 : 多次触发时只执行一次(如滚动)
const debounce = (func,wait=50) => {
let timer = 0;
return function(...args){
if(timer) ClearTimeout(timer)
timer = setTimeout(()=>{
func.apply(this,args)
},wait)
}
}
11、节流:多次执行变成每隔一段时间执行
12、继承:
原型链继承:子函数.prototype = new 父函数();
缺点:不能传参,包含引用类型的值,不能解耦,实例没有自己的属性;
借用构造函数继承:子函数方法里写 父函数.call(this),可以传参;
缺点:方法都在构造函数里面,不能复用;
组合继承:原型链继承+借用构造函数继承:
原型链继承原型的属性和方法
借用构造函数继承实例的属性和方法;
13、call、apply、bind区别
let a = {
value: 1
}
function getValue(name, age) {
console.log(name)
console.log(age)
console.log(this.value)
}
getValue.apply(a, ['啦啦啦', 18])
getValue.call(a, 'lelele', 19)
bind直接返回一个函数
14、Map、FlatMap、Reduce
map是生成一个新数组,将每个元素拿出来做变化然后放到新数组中。
[1,2,3].map(v=>v+1)
三个参数:当前索引,索引,原数组
FlatMap基本没啥用,和map差不多。就是会降维。
[1,[2],3].flatMap((v)=>v+1)
[1,2,3].reduce((a,b)=> a+b)
15、async 和 await
一个函数前加上async,该函数会返回一个Promise
async function(){
return '1';
}
console.log(test())
await 只能在async里面使用
async function test(){
let value = awiat sleep();
console.log("object");
}
只用async和await可以向同步代码一样写异步代码
16、Proxy
是es6中新增的功能,可以用来自定义对象中的操作
可以使用Proxy实现一个数据的绑定和监听
17、精度问题
为啥0.1+0.2 != 0.3?
可以使用parseFloat((0.1+0.2).toFixed(10))
18、创建对象:
工厂模式,批量创建相似的对象
缺点:只是创建相似对象,没有识别对象
构造函数模式:可以创建特定对象,比如原生的:Object,String,Math,Number,Array,Date,Boolean...
缺点:可以创建多个对象,但是内部创建多个方法时不方便,封装性不好
原型模式:xxx.prototype.name = aaa
缺点:单独使用原型模式会共享属性里面的数组或对象,不行!
最优解:组合使用构造函数模式和原型模式,构造函数里面定义实例属性,原型模式定义需要共享的属性和方法;
19、继承:
原型链继承:子函数.prototype = new 父函数();
缺点:不能传参,包含引用类型的值,不能解耦,实例没有自己的属性;
借用构造函数继承:子函数方法里写 父函数.call(this),可以传参;
缺点:方法都在构造函数里面,不能复用;
组合继承:原型链继承+借用构造函数继承:
原型链继承原型的属性和方法
借用构造函数继承实例的属性和方法;