JavaScript学习笔记

37 阅读4分钟

这是我参与【第四届青训营】笔记创作活动的第5天。

1、函数对象

1、call()和apply()

call()和apply()着两个方法都是函数对象的方法,需要通过函数对象来调用,当对函数调用call()和apply()都会调用函数执行,在调用call()和apply()可以将一个对象指定为第一个参数,此时着哥对象会成为函数执行时的this,call() 方法可以将实参在对象之后依次传递apply() 方法需要将实参封装到一个数组中统一传递。

  1. call()
      function fun(a, b) {
        console.log("a = " + a);
        console.log("b = " + b);
        console.log("fun = " + this);
      }
​
      var obj = {
        name: "obj",
        sayName: function () {
            console.log("obj--");
          console.log(this.name);
        },
      };
​
      fun(2, 3);
      console.log("===============");
      fun.call(obj, 2, 3);
      console.log("===============");
      obj.sayName();

image-20220704124553292

注意:默认fun()函数调用,this指向的是window对象,你可以使用call()调用函数,在调用的时候传入一个对象,这个对象就是this所指向的对象,也就是说,可以自己指定this的指向,然后从第二个参数开始,实参将会依次传递。

    function fun(a, b) {
        console.log("a = " + a);
        console.log("b = " + b);
        console.log("fun = " + this);
      }
​
      var obj = {
        name: "obj",
        sayName: function () {
          console.log(this.name);
        },
      };
​
      fun(2, 3);
      console.log("===============");
      fun.apply(obj, [2, 3]);

image-20220704125052944

注意:默认fun()函数调用,this指向的是window对象,你可以使用apply()调用函数,在调用的时候传入一个对象,这个对象就是this所指向的对象,也就是说,可以自己指定this的指向,然后从第二个参数开始,需要制定一个实参数组进行参数传递。

2、深拷贝和浅拷贝:

深拷贝:可以看成两个人拥有自己独自的房间,当a改变了自己房间的风格,b的房间还是b原来的风格,不受a的影响;

浅拷贝:a,b两人共用一个卧室

promise.all:当所有的异步都执行完之后才执行回调

promise.race:谁先执行完就以谁为准执行回调

Promise的执行顺序

Promise是宏任务(同步执行),但Promise的回调函数属于异步任务,会在同步任务之后执行(比如说:then,catch,finally)。

Promise的回调函数不是正常的异步任务,而是微任务(microtask)。它们的区别在于,正常任务追加到下一轮事件循环,微任务追加到本轮事件循。这意味着,微任务的执行事件一定早于正常任务。

3、什么是回调函数?

回调函数是指用一个函数作为参数传入另一个函数,这个函数会在某个时机被调用。

比如settimeout()等等

4、闭包

1、什么是闭包?

  1. 函数和对其周围状态(语法环境)的引用捆绑在一起构成闭包(closure)

2、闭包的三大特性

  1. 函数嵌套函数
  2. 函数内部可以引用函数外部的参数和变量
  3. 参数和变量不会被垃圾回收机制回收

也可以近似看成Java中的类的继承,外部函数看成父亲,内部嵌套的函数看成儿子,儿子可以继承父亲的属性,而且当儿子外出时,自己的东西就会消失,但是从父亲那继承而来的东西不会改变,回来以后还是外出前的状态,但儿子自身的东西就是刚出生的样子了

闭包的好处和坏处

好处

  1. 保护函数内的变量安全,实现封装,防止变量流入其他环境发生命名冲突;
  2. 在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存);
  3. 匿名函数自执行函数可以减少内存消耗;

坏处

  1. 其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法时可以在使用完成量后手动为它赋值为null;
  2. 其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨域作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响。