js 面经知识点整理第二弹(this指针 闭包) | 青训营笔记

104 阅读3分钟

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

作用域和自由变量

作用域:

代表了一个变量合法的使用范围

image.png

  • 全局作用域:

    一个被全局定义的变量,没有受到任何函数的约束,在全局都可以使用。

  • 函数作用域:

    在一个函数中定义的变量,只能在当前函数使用。

  • 块级作用域:

    这里的:是指 if, for, while 等后面有个大括号。

    在一个块中定义的变量,只能在当前块使用。

  • 自由变量:

    代表一个变量在当前作用域没有定义,但被使用了。

这时候,会向上级作用域,一层一层的查找,直至找到。

如果到全局作用域都没找到,则报错 xx is not define.

闭包

有两种表现:

1. 函数作为返回值

image.png

100

函数定义在create作用域, a = 100 也在create作用域

console.log(a),变量a先去定义的地方寻找。fn函数作用域里面没有,

因此是个自由变量,往上层查找,找到a = 100.

2. 函数作为参数被传递 :

image.png

100      

函数定义在全局作用域

a = 100 也在全局作用域

console.log(a),变量a先去定义的地方寻找。fn函数作用域里面没有,

因此是个自由变量,往上层查找,找到 a = 100.

 

总结: 闭包有两种形式,1: 函数作为返回值。2: 函数作为参数被传递。

      形成的原因是,函数中使用了自由变量。

闭包(或者说 所有变量的查找)中。自由变量的查找,是在函数定义的地方开始,向上级作用域查找,不是在执行地方!!!!

闭包常常由于,用于隐藏数据,如做一个简单的 cache 工具。这样缓存中 data 的就只能够通过提供的 set, get 方法操作进行数据的获取和写入。外界没有办法直接更改缓存中 data

image.png

image.png

this

this取什么值,是在函数执行时确定的!!!不是在函数定义时确定的。

应用场景:

(1)作为普通函数被调用

image.png

Window 

(2)使用 call apply bind去调用

call, bind(和call不同在于,返回一个函数执行)来改变this的指向  

(3)作为对象方法被调用

image.png

代表当前对象

!!! 注意️ set Timeout里面的this,指向一定是window。

             箭头函数里面的this,取它上级作用域的值。

(4)在class方法中被调用

image.png

代表正在创建的那个实例。

(5)箭头函数

箭头函数里面的this,取它上级作用域的值。

总结:

  • 当成普通函数被调用:window

  • 使用 call apply bind时: this绑定传入的对象

  • a.call(b,arg1,arg2..)   apply(obj,args)  bind时 

  • 在对象的方法中调用:对象本身

  • 在class的方法中调用:当前实例本身

  • setTimeout方法里面:window

  • 箭头函数:和上级作用域里this一致

实际开发中闭包的应用场景

举例说明:

用于隐藏数据,如做一个简单的cache工具。

这样data的值就只能够通过set, get方法操作,外界没有办法直接更改。

(只看script)

 

Js 创建10个 <a> 标签,点击的时候弹出对应的序号

// let i, a

这样会出现alert的一直是10。

因为代码执行很快就会执行完,遍历10遍,创建a标签,绑定事件。这个事件在此期间还没有执行。

这个事件什么时候click什么时候才执行,所以如果i是个全局的变量,执行的时候早就已经是10了。

  下面这样更改, i存储在块作用域,每次for循环都会形成一个新的块。i 就会在块级作用域找到。

参考链接:

www.cnblogs.com/xxcanghai/p…