闭包

闭包就是能够读取其他函数内部变量的函数,只有函数内部的子函数才能读取局部变量,主要是为了设计私有的方法和变量,优点是可以避免全局变量的污染,缺点是闭包会常驻内存,增大内存使用量,使用不当很容易早成内存泄漏。
自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方!!!

  1. function createCache() {
  2. const data = {}; // 闭包中数据被隐藏,外界无法访问
  3. return {
  4. set: function (key, val) {
  5. data[key] = val;
  6. },
  7. get: function (key) {
  8. return data[key];
  9. }
  10. };
  11. }

闭包一般有两种表现形式:
函数作为返回值被返回:

  1. function fn() {
  2. const a = 100
  3. return function () {
  4. console.log(a);
  5. }
  6. }
  7. const a = 200
  8. const res = fn()
  9. res() // 100

函数作为参数被传递:

  1. function print(fn) {
  2. const a = 100
  3. fn()
  4. }
  5. function fn() {
  6. console.log(a);
  7. }
  8. const a = 200
  9. print(fn) // 200

this指向

this 总是(非严格模式下)指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境

  • 全局环境中this指向全局变量window
  • 函数中的this,由调用函数的方式来决定
  • 构造函数里的this以及原型里的this对象指的都是生成的实例(由new决定的)
  • 箭头函数按词法作用域来绑定它的上下文,所以this 实际上会引用到原来的上下文

call、apply和bind

call和apply区别

几乎没有区别,当它们被设计出来时要做到的事情一摸一样,唯一的区别就在于传参的格式不一样

  • apply接受两个参数
    • 第一个参数指定了函数体内this对象的指向
    • 第二个参数为一个带下标的参数集合(可以是数组或者类数组)
  • call接受的参数不固定

    • 第一个参数指定了函数体内this对象的指向
    • 第二个参数及以后为函数调用的参数

      call和apply能做什么?

      使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数
  • 调用构造函数来实现继承;

  • 调用函数并且指定上下文的 this;
  • 调用函数并且不指定第一个参数;

借用其他对象的方法
我们可以直接传null来代替任意对象

  1. Math.max.apply(null, [1, 2, 3, 4, 5])

bind

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用