如何理解javascript词法作用域?

 

问题描述:

最近在看词法作用域,遇到一个例子不是很理解
var value = 1;
function foo() {
    console.log(value);
}
function bar() {
    var value = 2;
    foo();
}
bar(); //结果是1


function bar() {
    var value = 2;
    function foo() {
         console.log(value);
    }
    foo();
}

bar();//结果是2

第一个例子,在执行foo函数时先是从foo函数内部查找局部变量value,
因为foo函数中没有value变量所有又向上一层查找,此时查找的是全局
变量value=1,不太明白的是foo函数的上一层为什么不是bar函数?这两个例子
有什么区别吗?

 

第 1 个答案:

因为第一个foo是在外面定义的,它的上一层不是bar


 

第 2 个答案:

这里我的一些理解和解释,希望能对你有所帮助!

针对例一

1、解释:foobar兄弟关系,没用从属关系,但是可以互相调用
2、原例代码解释:

var value = 1;
function foo() {
    console.log(value);
}
function bar() {
    var value = 2; //在bar函数内容重新定义了一个局部变量,这儿并没有改变全局变量value的值
    foo(); //调用函数foo,首先在自己函数内部查找value值,没找到往上一层(这是就是全局)找,由于bar内部没能改变全局环境下的值,所以此时的值仍为1
}
bar(); //结果是1

3、代码举例:

3.1、在bar内部改变全局环境下的值
```
var value = 1;
function foo() {
    console.log(value);
}
function bar() {
    value = 2;  //去掉var声明,此时就是对全局环境下value值进行了重新赋值
    foo();
}
bar(); //结果是2
```

3.2、测试作用域
```
var value = 1;
function foo() {
    console.log(test); //在这儿获取bar内部的局部变量肯定不存在的
}
function bar() {
    var test = 2; //这是一个局部变量
    foo();
}
bar(); //报错,test is not defined;
```

针对例二

1、解释:barfoo是父子关系,子作用域当然可以打印父作用域下的变量
2、原例代码解释:

var value = 1;
function bar() {
    var value = 2;
    function foo() {
         console.log(value);
    }
    foo(); //调用时,先在foo内部找,没找到,去父作用域bar找,找到了,输出value的值,值为2,如果bar也没有找到,接着往上找,知道找到或者确认不存在而报错为止
}
bar();//结果是2

3、代码举例:

3.1、去掉bar内部的value声明和赋值
```
var value = 1;
function bar() {
    function foo() {
         console.log(value);
    }
    foo(); //此时会去找最外面那个value值了
}
bar();//结果是1
```
3.2、在foo内部再加一层复制
```
var value = 1;
function bar() {
    var value = 2;
    function foo() {
        var value = 3;
         console.log(value);
    }
    foo(); //此时会自己的作用域就用相应的变量值,就打印自己的值,不往上寻找
}
bar();//结果是3
```
不明之处,欢迎留言评论!

一个表中可能有20个字段,在对表进行查询时,只需要查询其中15个字段,请问下有没有直接排除剩下的5,而不把需要的15个字段一一写出来的方法?