JavaScript 环境和做用域

做用域

1. 全局环境

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

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

2. 局部环境

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

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

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

局部环境和全局环境的关系?
答: 局部环境能够经过做用域链访问递归上级局部环境和最终全局环境中的资源。this

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();

以下图:code

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 有块级做用域

块级做用域:由花括号{}所造成的做用域ip

  • 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() {}
相关文章
相关标签/搜索