本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
作用域
- 全局作用域,全局可用,可被局部作用域读取。
- 局部作用域(函数作用域),局部变量只在函数体内可见,因此也称为私有变量。
定义作用域
-
词法作用域:根据代码的结构关系确定作用域。
- 静态的词法结构
- JavaScript解析器主要根据词法结构确定每个变量的可见范围和有效区域。
-
执行作用域:当代码被执行时,才能确定变量的作用范围和可见性。
- 一种动态的作用域
- 作用域会因为调用对象不同而发生变化。
JavaScript支持词法作用域,JavaScript函数只能运行在被预先定义好的词法作用域里,而不是被执行的作用域里。
因此,定义作用域实际上就是定义函数
作用域链
-
作用域链是JavaScript提供的一套解决函数内部私有变量的访问机制。
-
JavaScript规定每一个作用域都有一个与之相关联的作用域链。
-
在访问私有变量的过程中,会从链首的对象开始,然后依次查找后面的对象,直到在某个对象中找到与私有变量名称相同的属性
-
如果在作用域链顶端(全局对象)中任然没有找到同名的属性,则返回undefined。
函数的私有变量
- 函数参数
- arguments
- 局部变量
- 内部函数
- this(动态引用当前运行环境)
ES6 块级作用域
- ES6引入了let 和 const
- {}包裹的就是块级作用域
- let 和 const 只能在块级作用域里作用
闭包
-
定义闭包
- 一个持续存在的函数上下文运行环境。
- 内部函数引用外部函数的私有变量,同时内部函数又被外界调用。当外部函数被调用时,就形成闭包,这个函数也称为闭包函数。
-
function f(x){ return function(y){ return x+y;//如果return的是一个简单变量,那么c得到的只是一个简单的值,而不是函数的引用。 }; var c = f(5);//function(y)一直被引用。 console.log(c(6)) }
-
使用闭包
-
//示例1 var f = function(){ var a = [] return function(x){ a.push(x); return a; }; }(); var a = f(1); console.log(a); var b = f(2); console.log(b); //在上面示例中,通过外部函数设计一个闭包,定义一个永久的储存器。 //当调用外部函数并生成执行环境之后,就可以利用返回的匿名函数,不断地向闭包体内的数组a传入新值, //传入的值会一直存在 -
//示例2 function f(){ var a = 1; b = function(){ console.log("a="+a); } c = function(){ a++; } d = function(){ a--; } } </script> <button onclick = "f()">生成闭包</button> <button onclick = "b()">查看a</button> <button onclick = "c()">递增</button> <button onclick = "d()">递减</button>
-