Skip to content

Latest commit

 

History

History
115 lines (81 loc) · 5.05 KB

variable-norm.md

File metadata and controls

115 lines (81 loc) · 5.05 KB

变量, 是编程语言的核心,也是编程语言的灵魂。那么JavaScript中的变量是怎么回事?

1 写在开始的废话

之前我写过一篇JavaScript中的四兄弟,介绍了JavaScript中声明变量的四种方式var,function,letconst。我就知道那个时候我就挖了一个坑,这篇文章我们详细一些。

2 导言

JavaScript中的变量可以在两个维度进行分类,①域, ②可变性

可变性
全局 值可变量
局部 常量

2.1 域(作用域)

什么是域? 可访问、操作一个变量的区域(范围)。有顶层域,也叫全局域,也有局部域,局部域可在函数和{}内产生。在全局域内创建的变量就是全局变量,以此类推,在局部域内创建的变量

作用域是在定义的时候产生的

 var name = 'jianyanzhi';

 function say() {
    var name = 'jianyanzhi-say';
    console.log(name);
    name = 'say-end-name';
    console.log('say-end-name:', name);
 }
 say();
 console.log(name);

上面这段代码哪些是全局变量哪些是局部变量呢?我们来分析一下。

Snipaste_2022-04-04_11-57-16.png

图中,红框的部分就是全局域,在全局域中,我们创建了namesay两个变量。再缩小范围,绿框的部分就是由函数say创建的局部域,在say中只创建了name这个变量,所以绿色下划线的name变量就是局部变量。而函数say中第三行又把name这个变量重新赋值,此时操作的是局部变量。

 var allowVar = 'jianyanzhi', allow = true;
 if (allow) {
     function allowFunction () {
         console.log('allow-say')
     }
     let allowLet = 'allowLet';
     const allowConst = 'allowConst';
     var allowVar = 'allowVar';
     console.log('allow', allowFunction);
     console.log('allow', allowLet);
     console.log('allow', allowConst);
     console.log('allow', allowVar);
 }
console.log('global', allowFunction);
console.log('global', allowVar);
console.log('global', allowLet);
console.log('global', allowConst);

同样的问题,哪些是局部变量,哪些又是全局变量?我们来分析下;

Snipaste_2022-04-04_12-37-05.png

代码执行的结果是什么?

allow "function allowFunction () {console.log('allow-say')}"
allow "allowLet"
allow "allowConst"
allow "allowVar"
global "function allowFunction () {console.log('allow-say')}"
global "allowVar"
ReferenceError allowConst is not defined // global "allowConst"
ReferenceError allowLet is not defined //  global "allowLet"

为什么会产生这样的结果?

  1. if条件语句中由varfunction创建的变量,会自动归到if语句所属的域中 因此我们看到global的输出中,varfunction的输出和allow的输出是一致的。不只是if语句,还有单纯的{}也是,比如{ var a = 1; function aFn() {} };
  2. varfunction创建局部变量的时候,只能在function中创建有效,var是无法在{}块级作用域中创建局部变量的;
  3. letconst创建的变量则属于声明时所在的域,包括函数和{}。

全局变量和局部变量的使用

  1. 全局变量作为持久性变量使用,全程有效,而不是拿来存储某个临时的值,谨慎修改

  2. 全局变量和局部变量存在同名的情况下,根据就近原则,优先使用局部变量,要防止污染全局变量

2.2 可变性

根据值的可变性来分类,可变的是变量,不可变的是常量。变量可后续随意更改,值是动态的,而常量一旦确定则无法修改,值是恒定、静态的。

var date = '2022-01-01';
const codeLang = 'JavaScript';
const articleData = { title: 'JavaScript中的变量', author: '简言之' };

date = '2022-04-04'; // success

codeLang = 'Java'; // TypeError: Assignment to constant variable

articleData = { title: 'haha', author: '简言之' } // TypeError: Assignment to constant variable
articleData['title'] = 'haha';  // success

创建了两个常量和一个变量。变量date后续可以随意更改,更改有效。 常量就无法更改了,codeLangarticleData在修改的时候抛出了类型错误。表示它们都是常量,无法更改。可为什么后面把title改为haha的时候就更改成功了?因为常量保存的是变量的值,这个值可以是一个普通值也可以是一个内存地址值,只要确保这个值是恒定的,其他由你使劲造

变量与常量的使用

  1. 根据编码逻辑来适当使用常量,虽然变量可满足所有要求,但是合适使用常量可以增强代码的语义性

  2. 上述案例中的articleData通过访问属性并修改值这种方式谨慎使用,修改的属性过多时,还是键值对合并之后保存到一个新常量中较为妥当