JavaScript作用域与JavaScript提升(Hoisting)

一、JavaScript作用域
 
作用域指的是有权访问的变量集合。
JavaScript函数作用域
在JavaScript中有两种作用域类型:局部作用域、全局作用域。JavaScript拥有函数作用域:每个函数创建一个新的作用域。作用域决定了这些变量的可访问性(可见性)。函数内部定义的变量从函数外部是不可访问的(不可见的)。
 
1.局部JavaScript变量
在JavaScript函数中声明的变量,会成为函数的局部变量。局部变量的作用域是局部的:只能在函数内部访问它们。
function myFunction() {
    var carName = "porsche";
    // 此处的代码能使用 carName 变量
 
}
由于只能在函数内部识别局部变量,因此能够在不同函数中使用同名变量。
在函数开始时会创建局部变量,在函数完成时会删除它们。
 
2.全局JavaScript变量
函数之外声明的变量,会成为全局变量。全局变量的作用域是全局的:网页的所有脚本和函数都能够访问它。
var carName = " porsche";
// 此处的代码能够使用 carName 变量
function myFunction() {
    // 此处的代码也能够使用 carName 变量
}
 
3.JavaScript变量
在JavaScript中,对象和函数也是变量。作用域决定了从代码不同部分对变量、对象和函数的可访问性。
(1)自动全局
如果为尚未声明的变量赋值,此变量会自动成为全局变量。
myFunction();
// 此处的代码能够使用 carName 变量
function myFunction() {
    carName = "porsche";
}
(2)严格模式
所有现代浏览器都支持以“严格模式”运行 JavaScript。在“严格模式”中不会自动创建全局变量。
(3)HTML中的全局变量
通过JavaScript,全局作用域形成了完整的JavaScript环境。在HTML中,全局作用域是window。所有全局变量均属于window对象。
var carName = "porsche";
// 此处的代码能够使用 window.carName
除非有意为之,否则请勿创建全局变量。
全局变量(或函数)能够覆盖window变量(或函数)。任何函数,包括window对象,能够覆盖全局变量和函数。
(4)JavaScript变量的有效期
JavaScript变量的有效期始于其被创建时。局部变量会在函数完成时被删除。全局变量会在您关闭页面是被删除。
 
4.函数参数
函数参数也是函数内的局部变量。
 
 
四、JavaScript提升(Hoisting)
 
提升(Hoisting)是JavaScript将声明移至顶部的默认行为。
 
1.JavaScript声明会被提升
在JavaScript中,可以在使用变量之后对其进行声明。换句话说,可以在声明变量之前使用它。
(1)例子1
x = 5; // 把 5 赋值给 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x;                     // 在元素中显示 x
(2)例子2
var x; // 声明 x
x = 5; // 把 5 赋值给 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x;                     // 在元素中显示 x
Hoisting是JavaScript将所有声明提升到当前作用域顶部的默认行为(提升到当前脚本或当前函数的顶部)。
 
2.let和const关键字
用let或const声明的变量和常量不会被提升!
 
3.JavaScript初始化不会被提升
JavaScript 只提升声明,而非初始化。
(1)例子1
var x = 5; // 初始化 x
var y = 7; // 初始化 y
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y;           // 显示 x 和 y
(2)例子2
var x = 5; // 初始化 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y;           // 显示 x 和 y
var y = 7; // 初始化 y 
 
说明:在顶部声明您的变量!
Hoisting(对很多开发者来说)是 JavaScript 的一种未知的或被忽视的行为。如果开发者不理解 hoisting,程序也许会包含 bug(错误)。为了避 bug,请始终在每个作用域的开头声明所有变量。由于这就是JavaScript解释代码的方式,请保持这个好习惯。严格模式中的JavaScript不允许在未被声明的情况下使用变量。