变量相关知识整理

关于变量的理解

何为变量? 简而言之就是存储数据值的容器,js所有变量都拥有唯一标识符,即我们通常说的变量名。

变量名称命名规则

  • 名称可包含字母、数字、下划线和美元符号($);
  • 名称必须以字母开头
  • 名称也可以 $ 和 _ 开头(不推荐使用)
  • 名称区分大小写
  • 保留字无法用作变量名称

关于变量,我们通常有两个操作,声明和赋值

变量作用域

变量作用域是指一个变量可以在哪一个范围内使用。
主要分全局作用域和函数作用域,而在ES6中新增的let和const的关键词可以在一对大括号之间{}形成块级作用域。
全局作用域

  • 全局作用域在页面打开时被创建,页面关闭时被销毁;
  • 拥有全局作用域的变量全局有效,在页面的任意位置都可以访问到;
  • 在函数外部声明的变量或在函数内部没有使用var关键字声明的变量具有全局作用域,可称为全局变量;
  • 全局作用域中声明的变量和函数会被挂载到全局对象window对象上,作为window对象的属性和方法保存,可通过 “window.变量名” 的方式访问到。

函数作用域

  • 调用函数时,函数作用域被创建,函数执行完毕,函数作用域被销毁;
  • 拥有函数作用域的变量只在该函数内部有效,在函数外部无法访问;
  • 在函数内部通过var关键字声明的变量具有函数作用域,可称为局部变量;
  • 每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的;
  • 在函数中定义形参,等同于声明变量。

块级作用域

  • ES6新增内容,包含在{}里的区域;
  • 使用let和const定义的变量具有 块级作用域。

变量搜索机制

当某个变量被访问时通常会经过以下步骤:

  1. 判断当前位置是否存在局部作用域(即函数作用域和块级作用域);
  2. 存在局部作用域,则判断该局部作用域内是否存在该变量名的变量;
  3. 若无,寻找上一级作用域,重复第二个步骤,直到全局作用域;
  4. 若全局作用域也找不到这个变量,这个变量就是未定义的 undefined。

变量提升

如果变量声明在函数里面,则将变量声明提升到函数的开头
如果变量声明是一个全局变量,则将变量声明提升到全局作用域的开头

变量声明之let、const、var

我们通常使用 var 关键词来声明 JavaScript 变量

var b;//声明变量b

变量声明之后,是没有值的,即为undefined。
在ES6中新增了两个关键词 letconst ,他们与 var 主要有以下区别:

  • var声明的变量会挂载在window上,而let和const声明的变量不会:
  var a=1;
  let b=2;
  const c=3;

  console.log(a,b,c); // 1,2,3
  console.log(window.a); //1
  console.log(window.b); //undefined
  console.log(window.c); //undefined
  • let 和 const 会在一对大括号内形成块级作用域,而var不会:
 if(1){
    var a=1;
    let b=2;
    const c=3;
  }
  console.log(a); // 1
  console.log(b); // b is not defined
  console.log(c); // c is not defined

let 和 const 会在 {} 内形成块级作用域,成为其内部的局部变量,因此在{}外无法访问。

  • var声明变量存在变量提升,let和const不存在变量提升
  console.log(a);
  console.log(b);
  console.log(c); 

  var a=1;
  let b=2;
  const c=3;

  console.log(a);
  var a; //变量提升
  
  console.log(a); //undefined,已经声明,还未赋值;
  console.log(b); //b is not defined
  console.log(c); //c is not defined

  a=1;
  let b=2;
  const c=3;

  console.log(a); // 1
  • const 为常量,一旦定义不可更改,而var,let为变量,可以改变其值:
  var a = 1;
  let b = 2;
  const c = 3;

  console.log(a); // 1
  console.log(b); // 2
  console.log(c); //3

  a = 4;
  b = 5;
  c = 6;  // 报错:Assignment to constant variable.  常量不可以再次赋值

  console.log(a); //4
  console.log(b); //5
  • 同一作用域下let和const不能声明同名变量,而var可以
var a=1;
let b=2;
const c=3;
console.log(a); //1
console.log(b); //2
console.log(c); //3

var a=4;
console.log(a); //4
// let b=5; //报错 : Identifier 'b' has already been declared
const c=6; //报错 : Identifier 'c' has already been declared
  • 存在暂时性死区
    暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。因此,一旦在某个作用域内存在let定义的变量,那该作用域内所有使用该变量名的变量都将值这一变量,而不再受外部变量的影响。
  var a=1;
  if(1){
    console.log(a); //a is not defined .此处的a指的是该作用域内let所声明的变量a,而不是外部的var声明a,只是let没有变量提升,所以此处的a还未声明,无法访问。
    let a=2;
  }
发布了1 篇原创文章 · 获赞 3 · 访问量 43

猜你喜欢

转载自blog.csdn.net/qq_43620719/article/details/104424344