JavaScript完全整理

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),可以传参;

缺点:方法都在构造函数里面,不能复用;

组合继承:原型链继承+借用构造函数继承:

原型链继承原型的属性和方法

借用构造函数继承实例的属性和方法;

你可能感兴趣的:(JavaScript完全整理)