词法作用域是什么?
js词法作用域是什么? 个人理解:它是一种规则,规定了我们的js程序按照特定方式去查找变量。词法作用域又叫静态作用域,函数的作用域在函数定义的时候就规定了。这个规则其实粗俗的理解就是就近原则,通过下方试验可得出。
// 示例一
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar(); // 1
这个结果输出是1 ,根据我们的词法作用域,我们的foo函数在定义阶段其实是跟bar函数没有关系的这只是两个函数,不关心函数内部。因此上面的代码也可以理解成下面 示例二:
// 示例二
var value = 1;
function foo() {
console.log(value);
}
bar(); // 1
在你写完第四行的时候作用域就决定了,value会先找同一级的,然后发现没有就会找上一级的,结果输出就为1。接下来变化一种形式如下:
// 示例三
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar();
这次这个会输出什么呢?根据上面的结论我们不难得出应该输出undefined,我们可以参考示例二来推出我们这个结果。函数定义阶段决定了我们js查找变量的方式,而不是调用阶段
示例(难度加深)
接下来升级一下难度,看如下的代码:
// 示例四
var scope = "global scope";
function checkscope() {
var scope = "local scope";
function func() {
return scope;
}
return func();
}
console.log(checkscope())
function checkscope2() {
var scope = "local scope";
function func() {
return scope;
}
return func;
}
console.log(checkscope2()())
这两个输出的结果都是local scope 不知道这个结果有没有让大家出乎意料。下面我给大家分析一下:
- 首先分析第一个函数:
- checkscope() 这个函数我们返回了func()
- 然后我们的func() 返回了scope
- 然后我们再调用checkscope(),就相当于则个返回值是scope,这个时候我们 函数checkscope()函数内有一个scope,全局中也有一个scope,还是根据我们的词法作用域,不管外面调用的是多么的花里胡哨,它的规则就是固定的,所以输出 local scope
- 然后分析第二个函数
- checkscope2() 这个函数返回了我们的func函数
- 然后我们checkscope2()()就相当于在全局中调用了我们的func()函数,它返回scope ,这里很容易迷惑我们,因我我们这个函数是在全局中执行的,那它的值是不是就变成了global scope?如果这样想,那就错了,我们一定要把词法作用域放在首位。func函数定义阶段始终不会改变,所以它一定还是local scope
为了让大家有更清晰的理解有了下面这个图(指出部分就是函数定义阶段):
词法作用域简单就讲到这里了,希望能让大家明白什么是词法作用域,和怎么判断一个变量的作用域(大致就是就近原则)。
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。
参考文档:
作者:Louis 深入学习js之——词法作用域和动态作用域
作者:冴羽 JavaScript深入之词法作用域和动态作用域