什么是作用域
作用域就是指当前执行代码所能访问变量的范围(权限) demo
let a = 1
function fn1() {
function fn2() {
console.log(a)
}
fn2()
}
fn1()
如上面代码,fn2的作用域就是fn2内部的环境,fn1的作用域就是fn1代码中的环境
什么是作用域链
作用域链就是指当前函数执行时需要访问一个变量,在当前执行函数的作用域中没有该变量,此时就会访问该函数的外部作用域,而如果当前执行函数的外部作用域也不包含该变量,则会继续向上访问至外部作用域的外部作用域,直到全局作用域,这就是作用域链
demo
let a = 1
function fn1() {
function fn2() {
console.log(a)
}
fn2()
}
fn1()
fn2在打印变量a时首先时访问当前执行函数的作用域,如果fn2作用域中没有,则会向上至fn1中找,fn1中也没有,则会继续找到全局作用域中,此时a变量就声明在全局作用域中
词法作用域(静态作用域)/动态作用域
- 词法作用域:函数的作用域在函数定义的时候就已经决定了
demo
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar();
由于JavaScript采用的静态作用域,所以foo的作用域在定义的时候就已经确定了,foo函数在执行时首先访问的时它自己的作用域,没有找到value值,因此会范文foo的外部作用域,也就是当前代码的全局作用域,全局作用域中的value是1,所以打印的值是1
- 动态作用域:函数的作用域在函数调用执行的时候确定
demo: bash语言就是动态作用域
value=1
function foo () {
echo $value;
}
function bar () {
local value=2;
foo;
}
bar
bash语言中foo函数的作用域确定时间是在foo调用时,而它调用时它的外部作用域是bar,访问的时候自然会访问到value=2
var、let、const声明的块作用域/函数作用域
var声明:var声明的变量只有函数作用域没有块级作用域 let,const声明:let和const声明的既有函数作用域也有块级作用域 demo
function fn() {
console.log(a)
console.log(b)
console.log(c)
var a = 1
let b = 2
const c = 3
console.log(a)
console.log(b)
console.log(c)
}
这时打印结果会报错,但是会提示b未定义,因为var声明的变量在当前的作用域内具有变量提升的效果,会将该声明变量提升到当前作用域的顶部,因此在当前函数的作用域下都可以访问到a变量,不同的是在a变量声明的上方访问值是Undefined,因此说var声明的变量只有函数作用域
而let和const声明的变量不能提升,只能在声明的下面使用,这个作用域就是块级作用域,同时在函数中该声明的下面也都可以使用,因此说let和const声明既有块级作用域也有函数作用域
思考题
想一想下面的两道题执行结果
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!