JavaScript 环境和作用域

Posted 两只小蚂蚁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 环境和作用域相关的知识,希望对你有一定的参考价值。

作用域

1. 全局环境

window: JS的全局执行环境,顶层对象。this指针在全局执行环境时就指向window。

console.log(this===window); //true

2. 局部环境

什么情况会具有局部环境?
答: function声明(包括常规声明,箭头函数,匿名函数)的花括号{}内部会形成局部环境。

let a = 1;
(()=>{let a = 2;})();
(function(){let a = 2;})();
function f1()
{
    let a = 3;
}
f1();

局部环境有什么特征?
答: 局部环境是运行在全局环境下的一个独立环境,局部环境可以嵌套。

局部环境和全局环境的关系?
答: 局部环境可以通过作用域链访问递归上级局部环境和最终全局环境中的资源。

3. 作用域链

从当前环境的arguments对象开始,到包含该环境的下一个环境的所有变量,一直到全局环境的变量,形成一个作用域链。

var color = "blue";
function changeColor(){
    var anotherColor = "red";
    function swapColors(){
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
        console.log(this);
        // 这里可以访问color、anotherColor 和tempColor
    }
    // 这里可以访问color 和anotherColor,但不能访问tempColor
    swapColors();
}
// 这里只能访问color
changeColor();

如下图:

window
  |__color
  |__changeColor()
    |__anotherColor
    |__swapColors()
      |__tempColor

注意:function内部不带类型的变量声明将会被定义到全局环境

function Fun(){
    var a = 1;
    b = 2;
}
Fun();
console.log(a);//not defined
console.log(b);//2

4. 没有块级作用域 VS 有块级作用域

块级作用域:由花括号{}所形成的作用域

  • ES5以前没有块级作用域
  • ES6使用let和const,则具有块级作用域特性
//a.js
var a = 1;
if(true)//if语句后的{}并不会形成块级作用域,其中的代码还是运行在顶级作用域
{
    var a = 2;//变量覆盖
}
console.log(a);//2
//b.js
if(true)
{
    var a = 1;//定义到全局
    let b = 2;//块级内部有效
    const c = 3;//块级内部有效
}
console.log(a); //1
console.log(b); //not defined
console.log(c); //not defined
//c.js
var a = 0;
(function fun1()
{
    var a = 1;
    let b = 2;
    const c = 3;
})()
console.log(a); //0
console.log(b); //not defined
console.log(c); //not defined

5. 变量提升

变量提升:在指定作用域里,从代码顺序上看是变量先使用后声明,但运行时变量的 “可访问性” 提升到当前作用域的顶部,其值为 undefined ,没有 “可用性”。
函数提升:同理,但只有函数声明式才存在函数提升,匿名函数和函数引用不会

看个例子就清楚了:

var i = 5;
function func() {
    console.log(i);//undefined
    var i = 6;
    console.log(i);//6
}
func();
//根据JS引擎的编译,实际上的代码运行如下
var i = 5;
function func() {
    var i;
    console.log(i);//undefined
    i = 6;
    console.log(i);//6
}
func();
//函数提升如下
console.log(f1()); //aa
console.log(f2); //undefined
function f1() {console.log(‘aa‘)}
var f2 = function() {}









以上是关于JavaScript 环境和作用域的主要内容,如果未能解决你的问题,请参考以下文章

深入理解javascript中执行环境(作用域)与作用域链

JavaScript运行环境和作用域链

Javascript执行环境作用域作用域链

javascript 作用域学习与总结

作用域是什么?

第四章—变量,作用域和内存问题