小白也能看得懂的JS基础之var let const的使用

小白也能看得懂的JS基础之var let const的使用

var

在js中,万物皆可var

当你需要声明一个数字,字符串,布尔值甚至是数组或者对象的时候你都可以

// 用var声明数字,字符串,布尔值,数组,对象
var num = 1;

var str = 'Hello World';

var bool = true;

var arr = [];

var obj = { name: 'hulh', age: 23, gender: 'male' };

基本上,你可以用var声明所有的数据类型

使用var声明变量的时候,你可以不用初始化值,只是声明。此时所声明变量的值为undefined。

var name;
console.log(name); // undefined

但是,我们还是建议:尽量在声明变量的时候给它指定一个初始值,以免发生不可预知的错误。

使用var声明变量,你还可以重复声明同一变量,因为Javascript是逐行编译,因此后面声明的同名变量会覆盖前者。

var name = 'hlh';
console.log(name); // hulh

var name = 'HLH';
console.log(name); // HLH (不会报错)

此外,用var声明变量,会发生“变量提升”的现象,何为变量提升呢?通俗点说就是,你可以在定义这个值之前去使用它。

console.log(name); // 不会报错,而是会输出undefined(当然,仅限非严格模式下)
var name = 'hulh';

为何会发生这个现象呢?是因为Javascript编译器会在编译时会将所有的声明提升到作用域的顶部,所以上述代码看起来就像是下面这样:

var name;
console.log(name); // 不会报错,而是会输出undefined(当然,仅限非严格模式下)
name = 'hulh';

Javascript中有全局变量和局部变量,用var声明的变量,在浏览器环境中默认会挂载到window对象下,成为window对象的一个属性。
而当不使用var声明变量的时候,在浏览器环境中也会自动挂载到window对象下(相当于声明了一个全局变量,容易污染全局变量)。在这里插入图片描述


let

let的作用与var差不多,但有一些区别:

let 声明的范围是块级作用域(ES6中新增了块级作用域),块级作用域由最近的一对大括号界定{},而 var 的声明范围是函数作用域
因此而发生的改变有:

// var
if (1) {
	var name = 'hlh';
}
console.log(name); // hlh

// let
if (1) {
	let name = 'hlh';
}
console.log(name); // 报错 name is not defined

let 声明的变量会形成暂时性死区,在这个块作用域内用 let 声明的变量,都不可以再重复声明,也不能在声明之前使用。
严格来讲,其实使用 let 声明的变量也会存在“变量提升”现象,但是因为暂时性死区的缘故,“变量提升”现象能够比较好的避免。
从某种角度来说,varlet 的“变量提升”是不一样的。

// 不能在声明之前使用
console.log(name); // 报错
let name = 'hlh';
// 不能重复声明
let name = 'HLH'; // Uncaught SyntaxError: Identifier 'name' has already been declared

在浏览器环境下,使用let声明的变量不会挂载到window上成为window的属性,避免了全局变量的污染。
在这里插入图片描述


const

varlet用于定义变量,即可变的量
const 用于定义常量,即不可变的量
const 定义的常量是只读的,无法修改

一个很经典的例子:

/*
 * 我们都知道圆的面积计算公式是 S = π * r * r
 * π 是一个永恒不变的值,假如我们用 var 或者 let 
 * 去声明的话,这个值就可能会意外的被改变
 * 此时我们用 const 去声明,就可以避免值被改变
*/
let PI = 3.1415926;
PI = 3.1233333; // 不可

const PI = 3.1415926;
PI = 3.1233333; // Uncaught TypeError: Assignment to constant variable.

使用 const 声明常量,一旦声明就必须赋值,否则会报错

const PI; // Uncaught SyntaxError: Missing initializer in const declaration

const 声明的常量与 let 声明的变量一样,同样存在暂时性死区,声明的范围也是块级作用域,同样不可重复声明

// 暂时性死区
console.log(PI); // ReferenceError: Cannot access 'PI' before initialization
const PI = 3.1415926;

// 块级作用域范围
if (1) {
	const PI = 3.1415926;
	console.log(PI); // 3.1415926
}
console.log(PI); // ReferenceError: PI is not defined

// 不可重复声明 
const PI = 3.1415926;
const PI = 3.14; // SyntaxError: Identifier 'PI' has already been declared

也许有些人会问,当我用 const 声明对象的时候,为什么对象的属性可以被改变?

大家都知道,声明对象时,javascript编译器会在堆内存中开辟出一块地址用以存放该对象,而 const 定义的常量存放的只是该对象的地址指针而已,只要地址指针没有改变,就没有违背不可改变的原则
我们修改对象的属性时,操作的是堆内存中的对象,并非 const 定义的这个常量本身,假如我们修改了这个常量的值,才会报错

更详细的解释可以参见:ECMAScript6入门(阮一峰) let和const命令 const 本质

const obj = {
	name: 'hlh',
	age: 23,
};
console.log('before', obj);
obj.name = 'HLH'; // 不会报错
console.log('after', obj);

/**
 * if we change the constant obj,
 * we actually modify the address of the obj.
 */
obj = {
	name: 'HuLiehao',
	age: 23,
	gender: 'male',
}; // Uncaught TypeError: Assignment to constant variable.

综上所述

我们在声明变量时应该优先使用 let ,定义常量则使用 const

以上

仅为本人拙见,如有错误或遗漏,请不吝赐教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值