JavaScript学习笔记:变量

在很多语言当中都有变量,而这也是基础知识。在JavaScript中也有变量,而最近也在学习有关于这方面的知识。今天就来总结一下JavaScript中有关于变量的一些基础知识。

变量命名规则

在JavaScript中可以用变量来为值命名。变量的名称称为identifiers,需要遵守一定的规则。

JavaScript中的变量名(也可称作是一个标识符identifier),其命名有一定的规则:

  • 必须以字母、下划线(_)或者美元符号($)开头,后续的字符可以包含数字(0-9),比如num_name$doc等;
  • 变量命名区分大小写,大写字母可以是大写的(A~Z)和小写的(a~z);

声明方式

JavaScript中有三种声明方式:

  • var: 声明变量,可选择将其初始化为一个值。详细介绍
  • let: 声明块范围局部变量,可选择将其初始化为一个值。详细介绍
  • const: 声明一个只读命名常量。 详细介绍

声明变量

声明变量常见的方式有以下三种方式。

  • 使用关键词var
  • 直接赋值
  • 使用关键词let

使用关键词var

使用关键词var声明了一个变量,并且可以同时初始化该变量。例如:

var i;
var num;
var a, b;
var name ='bingdian';
var i = 0, j = 1 , k=6;

使用var关键词声明的变量根据变量的作用域,又可以分为全局变量局部变量。而全局变量和局部变量又是一个令人头痛的概念,特别是对于一位初学者,更是令人模糊。后面我们专门来讨论和学习这个概念。

而且使用var关键词声明的变量是永久的,用delete运算符删除这些变量将会引发错误:

var a = 1;
b = 2;
delete this.a; // 在严格模式(strict mode)下抛出TypeError,其他情况下执行失败并无任何提示。
delete this.b;

console.log(a, b); // 抛出ReferenceError。
// 'b'属性已经被删除。

直接赋值

在代码中可以直接给一个声明名符赋值,如:

x = 42;

这样就创建了一个全局变量,并会导致JavaScript编译时产生一个严格警告。在代码中强烈建议不采用这种方式声明一个变量。

使用关键词let

关键词let是ES6中新增的一个命令,用来声明一个块级域的本地变量,并且可以同时初始化该变量。它的用法类似于var,只不过let声明的变量只在代码块内有效

{
    let a = 10;
    var b = 10;
    console.log(a); // 10
}

console.log(a); // Uncaught ReferenceError: a is not defined
console.log(b); // 10

上面的代码在代码块中,分别使用letvar声明两个变量。然后在代码块内调用这两个变量,返回的值都是正确的值。但在代码块之外调用这两个变量,结果let声明的变量报出Uncaught ReferenceError: a is not defined的错误信息,而使用var声明的变量返回正确的值为10。这也再次证明let声明的变量只在它所在的代码块有效。

let vs var

简单点说,let的作用域是块,而var的作用域是函数(要么是全局,要么是局部):

var a = 5;var b = 10;
if (a !== undefined) {
    let a = 10; // 域在if块内
    var b = 5; // 域在函数内
    console.log(a); // 10
    console.log(b); // 5
}
console.log(a); // 5
console.log(b); // 5

还有一点var可以重复声明同一个变量,而let不允许在相同的作用域内重复声明一个变量。如:

function func1(){
  let a = 'qdskill';
  var a = 'blog';
  console.log(a);
}
func1();
// repl: Duplicate declaration "a"
function func2(){
  var a = "qdskill";
  var a = "blog";
  console.log(a);
}
func2(); // blog

使用var关键词声明的变量,变量可以提升,而let关键不存在变量提升。来看两段代码:

console.log(foo); // ReferenceError
let foo = 2;

而使用var则不会报错

console.log(foo); // undefined
var foo = 2;

在使用var声明变量时,一个函数中所有的var语句应尽可能地放在接近函数顶部的地方。

常量

前面提到过,JavaScript中有三种声明方式,其中const关键词就是用来创建一个只读的常量。常量标识符的命名规则和变量的相同。

使用const声明的常量的值只要一旦声明了,就不能再改变。

const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: "PI" is read-only

上面的代码表明改变常量的值会报错。

const声明的变量,只要声明了就能不改变,所以就必须立即初始化,不能留到后面来赋值,不然就会报错。

const foo;
// SyntaxError: missing = in const declaration

constlet作用域是相同的,只在声明所在的块级作用域内才有效。

if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined

const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。

if (true) {
  console.log(MAX); // ReferenceError
  const MAX = 5;
}

上面代码在常量MAX声明之前就调用,结果报错。

const声明的常量,也与let一样不可重复声明。

var message = "Hello!";
let age = 25;
// 以下两行都会报错
const message = "Goodbye!";
const age = 30;

一个常量不能和它所在作用域内的其他变量或函数拥有相同的名称。

下面的例子演示了常量的特性。在浏览器的控制台度一下这个例子:

// 注意: 常量在声明的时候可以使用大小写,但通常情况下会使用全部大写英文。 
// 定义常量MY_FAV并赋值7
const MY_FAV = 7;
// 在 Firefox 和 Chrome 这会失败但不会报错(在 Safari这个赋值会成功)
MY_FAV = 20;
// 输出 7
console.log("my favorite number is: " + MY_FAV);
// 尝试重新声明会报错 
const MY_FAV = 20;
//  MY_FAV 保留给上面的常量,这个操作会失败
var MY_FAV = 20; 
// MY_FAV 依旧为7
console.log("my favorite number is " + MY_FAV);
// 下面是一个语法错误
const A = 1; A = 2;
// 常量要求一个初始值
const FOO; // SyntaxError: missing = in const declaration
// 常量可以定义成对象
const MY_OBJECT = {"key": "value"};
// 重写对象和上面一样会失败
MY_OBJECT = {"OTHER_KEY": "value"};
// 对象属性并不在保护的范围内,下面这个声明会成功执行
MY_OBJECT.key = "otherValue";

对变量求值

varlet声明的未赋初始值的变量,值都会被设定为undefined。所以我们就可以通过这样的方法了判断一个变量是否赋予了初始值:

var a;if (a === undefined) {
    ...
} else {
    ...
}

undefined值在布尔类型环境中会被当作false。例如,下面的代码将运行函数myFunction,因为数组myArray中的元素未被赋值:

var myArray = new Array();
if (!myArray[0]) myFunction();

数值类型环境中undefined值会被转换为NaN:

var a;
a + 2; // NaN

当你对一个空变量求值时,空值null在数值类型环境中会被当作来对待,而布尔类型环境中会被当作false。例如:

var n = null;
console.log(n * 32); //  0

变量的真相

可能很多人已经注意到,在 Javascript 当中,一个变量与一个对象的一个属性,有很多相似的地方,实际上,它们并没有什么本质区别。在 Javascript 中,任何变量都是某个特定对象的属性。

全局变量都是全局对象的属性。在 Javascript 解释器开始运行且没有执行 Javascript 代码之前,会有一个全局对象被创建,然后 Javascript 解释器会给它与定义一些属性,这些属性就是我们在 Javascript 代码中可以直接使用的内置的变量和方法。之后,每当我们定义一个全局变量,实际上是给全局对象定义了一个属性。

在客户端的 Javascript 当中,这个全局变量就是 Window 对象,它有一个指向自己的属性 window ,这就是我们常用的全局变量。

对于函数的局部变量,则是在函数开始执行时,会有一个对应的调用对象被创建,函数的局部变量都作为它的属性而存储。这样可以防止局部变量覆盖全局变量。

变量作用域

文章开头简单提到了变量是有作用域一说,分为全局变量和局部变量。而这两个概念对于初学者来说非常让人头疼。在这里暂不介绍,待后面了解了,再来说。

初学者学习笔记,如有不对,还希望高手指点。如有造成误解,还希望多多谅解。

原文链接:https://www.w3cplus.com/javascript/basic-of-the-javascript-variable.html

发表评论

登录后才能评论