JS(作用域与闭包)
1.对变量提升的理解
1.变量定义(上下文)
2.函数声明
2.说明 this 几种不同的使用场景
常见用法
1.作为构造函数执行
2.作为对象属性执行
3.作为普通函数执行(this === window)
4.call apply bind
3.创建10个 <a>标签,点击的时候弹出来对应的序号
结果:均显示
这种的结果是:每次点击时 i 都为10;点击 click 时,弹出 i,i 是自由变量,这时 i 已经变为 10了,故每次输出都为10;i 是全局作用域,存在覆盖的问题
使用 i 将函数包住,相当于创建 10 个函数 i ,不存在覆盖问题。
自执行函数:不用调用,只要定义完成,立即执行的函数(i 为 自执行函数)
4.如何理解作用域
1.自由变量(当前作用域没有定义的变量)
2.作用域链(自由变量的查找)
变量与函数的查找规则: 当我们调用一条数据的时候,js首先会在当前作用域中进行查找,如果找不到,就向上找到父级的作用域,如果在父级的作用域中也找不到,就继续向上查找,直到window的作用域。如果在window中也找不到,就报错了
3.闭包的两个场景:1.函数作为返回值2.函数作为参数传递
5.实际开发中闭包的应用
封装变量,收敛权限(不能更改的部分)
检验该数组是否在之前存在过
闭包的意义:在 isFirstLoad 函数外面,根本不可能修改掉 _list 的值(没来过的就是 < 0)
一、执行上下文
1.范围:一段<script>或者一个函数 (都会生成一个执行上下文)
2.全局:变量定义、函数声明 (一段<script>先将变量定义和函数声明拿出来)
3.函数:变量定义、函数声明、this、arguments (一个函数在执行之前姜变量定义、函数声明、this、arguments 拿出来)
函数声明:
将整个函数拿出来,故 function fn(name) 输出为 'zhangsan' 20
函数表达式:
先将变量定义拿出来,即将 a 拿出来,故console.log(a) 输出 undefined(代替)
(不推荐这样写,应将 定义 var a = 100 放在前面)
二、this
this 要在执行时(函数后面有())才能确认值,定义时无法确认
常见用法
1.作为构造函数执行
2.作为对象属性执行
3.作为普通函数执行(this === window)
4.call apply bind
结果:
三、作用域
1.没有块级作用域
因为 JS 中没有块级作用域,所以在{}里声明变量和在 if 之前声明变量是一样的(但尽量不要在块级作用域里面声明变量,不易读)
推荐写法:
2.只有函数和全局作用域
为保证变量不会被污染,可以将所有的变量定义在一个大的函数里。
作用域(scope):一条数据可以在哪个范围中使用。 通常来说,一段程序代码中所用到的数据并不总是有效/可用的,而限定这个数据的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强程序的可靠性,减少名字冲突。
变量(数据)js中,变量的作用域有两中,一种是全局作用域(全局变量) ,一种局部作用域(局部变量),一个变量是全局变量还是局部变量,主要看变量声明的位置。声明在函数内部,就是这个函数(function)的局部变量。
全局作用域 --- 在任何地方都能访问 函数外定义的变量拥有全局作用域 不使用var定义的变量拥有全局作用域 所有window对象上的属性拥有全局作用域 没有声明在任何函数内部的函数拥有全局作用域 局部作用域 --- 只能在函数内部访问 使用var在函数内部定义的变量,和使用function在函数内部声明的函数,拥有局部作用域
四、作用域链
1
2
3
4
5
|
var
b = 200
console.log(a)
console.log(b)
|
执行 console.log(a)时,在其父集作用域中去找 a,父集作用域为全局作用域,故 a 找到 var a = 100;
结果:100 200 300
寻找父集作用域要关注函数声明定义的位置;F1 的父集作用域为 a ,F2 的父集作用域为 F1故输出结果:100 200 300,这种寻找方式即为作用域链
变量与函数的查找规则: 当我们调用一条数据的时候,js首先会在当前作用域中进行查找,如果找不到,就向上找到父级的作用域,如果在父级的作用域中也找不到,就继续向上查找,直到window的作用域。如果在window中也找不到,就报错了
五、闭包
函数 F1 最后返回一个函数 a,F1 赋值给 f1,所以 f1 为函数, 最终执行 f1(),输出 100;
过程如下:执行 f1()---执行F1---执行函数 a---在 a 的父集作用域 F1 中寻找a---a = 100
var a =200 中的 a 是全局作用域,与 var a = 100 无关系
里面可以访问外边的,但是外边不能访问里边的。 闭包: 形式函数中套了一个函数,内层函数可以访问外层函数中的局部数据
闭包使用场景
1.函数作为返回值(如上所述)
2.函数作为参数传递
把函数传到另一个函数中执行
过程:执行 F2---执行 f1---执行 F1 ---执行函数 a---在其父集作用域中寻找 a --- a=100