2

JavaScript中的变量作用域与提升

 2 years ago
source link: https://segmentfault.com/a/1190000041357601
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

JavaScript中的变量作用域与提升

发布于 1 月 29 日

JavaScript中的变量作用域与提升

之前有看到一些对应的文章,但是对于变量作用域和提升的掌握理解的不够彻底,今天就来理一下。

首先,要知道,在ES6之前,JS中只存在函数作用域。let、const等变量声明关键字和块级作用域都是ES6才有的。

先看看作用域的定义:作用域就是指代码执行过程中的变量、函数或者对象的可访问区域。

最简单的例子就是函数外无法访问函数内定义的变量

var name1 = 'name1';
function logName() {
  var name2 = 'name2'
  console.log(name2)
}

logName()
console.log(name1)
console.log(name2)

在执行console.log(name2)的时候会报错,说name2未定义

块级作用域举一个简单的例子

 let a = 1
   {
​    let b = 3
​    a = 2
   }
   console.log(a)
   console.log(b)
  }
  test()

上述代码执行时同样会报错说b变量没有定义。

作用域解释起来比较简单,毕竟场景没多少个,好罗列一些。

变量提升的话,就要好好看看了

同样的,首先看几个例子,有兴趣的可以先自己尝试下对应的执行过程

//1

function test () {
    console.log(a);  //undefined
    var a = 123; 
};
test()
function test () {
    var a;
    console.log(a);
    a = 123;
}
test();

这意味着使用var声明的变量会提升到作用域的顶端

// 第二个例子
console.log(v1);
var v1 = 100;
function foo() {
    console.log(v1);
    var v1 = 200;
    console.log(v1);
}
foo();
console.log(v1);

这就涉及另一个知识点了:变量的就近查找。上面代码中foo函数中也有定义v1所以在foo函数中的实际顺序是这样的

function foo() {
    var v1
    console.log(v1);
    v1 = 200;
    console.log(v1);
}

咳咳,只是定义提升,赋值的代码还是原位置不动哈

此外,如果定义到函数外,并使用var关键字就会绑定到全局上,成为全局变量。

// 例子3
var a = 1
  function test(a) {
   console.log(a)
   var a = 11
   console.log(a)
  }
  test(a)

如果传入的形参跟外部变量名重复的话,优先级是等同的

这是因为JS中,执行一个函数时,形参和局部变量是存在一个活动对象里的,或者叫变量对象,如果在局部变量中定义了一个和形参相同名字的变量,编译器会忽略这个定义,而所有对该变量的操作都会反映到形参的那个变量中去。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK