Js-w3school(2020.2.6)【js作用域、js提升(Hoisting)】

二十二、js作用域和提升(Hoisting)

1.作用域指的是您有权访问的变量集合。在 JavaScript 中有两种作用域类型:
• 局部作用域:在 JavaScript 函数中声明的变量,会成为函数的局部变量。局部变量的作用域是局部的:只能在函数内部访问它们。由于只能在函数内部识别局部变量,因此能够在不同函数中使用同名变量。在函数开始时会创建局部变量,在函数完成时会删除它们。
• 全局作用域:函数之外声明的变量,会成为全局变量。全局变量的作用域是全局的:网页的所有脚本和函数都能够访问它。如果您为尚未声明的变量赋值,此变量会自动成为全局变量。(在“严格模式”中不会自动创建全局变量。)在 HTML 中,全局作用域是 window。所有全局变量均属于 window 对象。
2. JavaScript 拥有函数作用域:每个函数创建一个新的作用域。
3. 作用域决定了这些变量的可访问性(可见性)。
函数内部定义的变量从函数外部是不可访问的(不可见的)。
4. 任何函数,包括 window 对象,能够覆盖您的全局变量和函数。
5. JavaScript 变量的有效期:
JavaScript 变量的有效期始于其被创建时。
局部变量会在函数完成时被删除。
全局变量会在您关闭页面是被删除。
6. 函数参数也是函数内的局部变量。

二十三、js提升(Hoisting)

1.提升(Hoisting)是 JavaScript 将声明移至顶部的默认行为。(提升到当前脚本或当前函数的顶部)
2. 在 JavaScript 中,可以在使用变量之后对其进行声明。
换句话说,可以在声明变量之前使用它。

x = 5; // 把 5 赋值给 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x;                     // 在元素中显示 x
var x; // 声明 x
  1. let 和 const 关键字
    用 let 或 const 声明的变量和常量不会被提升。这两个关键字在 JavaScript 中提供了块作用域(Block Scope)变量(和常量)。
    (1)let块作用域
{ 
  var x = 10; 
}
// 此处可以使用 x

{ 
  let x = 10;
}
// 此处不可以使用 x

let在块内重新声明变量不影响块外

var x = 10;
// 此处 x 为 10
{ 
  var x = 6;
  // 此处 x 为 6
}
// 此处 x 为 6
var x = 10;
// 此处 x 为 10
{ 
  let x = 6;
  // 此处 x 为 6
}
// 此处 x 为 10

(2)let、const同作用域下重新声明不允许

var x = 10;       // 允许
let x = 6;       // 不允许

{
  var x = 10;   // 允许
  let x = 6;   // 不允许
}
let x = 10;       // 允许
let x = 6;       // 不允许

{
  let x = 10;   // 允许
  let x = 6;   // 不允许
}
let x = 10;       // 允许
var x = 6;       // 不允许

{
  let x = 10;   // 允许
  var x = 6;   // 不允许
}
const x = 2;       // 允许
const x = 3;       // 不允许
x = 3;             // 不允许
var x = 3;         // 不允许
let x = 3;         // 不允许

{
  const x = 2;   // 允许
  const x = 3;   // 不允许
  x = 3;         // 不允许
  var x = 3;     // 不允许
  let x = 3;     // 不允许
}

在不同的作用域或块中,通过 let 、const重新声明变量是允许的:

let x = 6;       // 允许

{
  let x = 7;   // 允许
}

{
  let x = 8;   // 允许
}
const x = 2;       // 允许

{
  const x = 3;   // 允许
}

{
  const x = 4;   // 允许
}

(3)let循环作用域
如果在循环中用 let 声明了变量 i,那么只有在循环内,变量 i 才是可见的。

let i = 7;
for (let i = 0; i < 10; i++) {
  // 一些语句
}
// 此处 i 为 7

(4)let函数作用域
在函数内声明变量时,使用 var 和 let 很相似。它们都有函数作用域
(5)let全局作用域
如果在块外声明声明,那么 var 和 let 也很相似。它们都拥有全局作用域
(6)let全局变量
在 HTML 中,全局作用域是 window 对象。通过 var 关键词定义的全局变量属于 window 对象:

var carName = "porsche";// 此处的代码可使用 window.carName

通过 let 关键词定义的全局变量不属于 window 对象:

let carName = "porsche";// 此处的代码不可使用 window.carName

(7)通过 var 声明的变量会提升到顶端。您可以在声明变量之前就使用它
通过 let 定义的变量不会被提升到顶端。在声明 let 变量之前就使用它会导致 ReferenceError。变量从块的开头一直处于“暂时死区”,直到声明为止
通过 const 定义的变量不会被提升到顶端。const 变量不能在声明之前使用
(8)通过 const 定义的变量与 let 变量类似,但不能重新赋值
(9)const 在声明时赋值
JavaScript const 变量必须在声明时赋值:

const PI;
PI = 3.14159265359;//不正确
const PI = 3.14159265359; //正确

(10)const不能改变原始值
(11)const可以改变原始对象属性

// 您可以创建 const 对象:
const car = {type:"porsche", model:"911", color:"Black"};
// 您可以更改属性:
car.color = "White";
// 您可以添加属性:
car.owner = "Bill";

但是您无法重新为常量对象赋值

const car = {type:"porsche", model:"911", color:"Black"};
car = {type:"Volvo", model:"XC60", color:"White"};    // ERROR

(12)const常量数组可以更改,单不能重新赋值(类比(11)对象)
4. JavaScript 初始化不会被提升
JavaScript 只提升声明,而非初始化。

var x = 5; // 初始化 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y;           // 显示 x 和 y,x is 5 and y is undefined
var y = 7; // 初始化 y 

5.为了避免 bug,请始终在每个作用域的开头声明所有变量。

发布了41 篇原创文章 · 获赞 4 · 访问量 1640

猜你喜欢

转载自blog.csdn.net/mus123/article/details/104199841