console.log(a); // undefined ===> a已声明还没赋值,默认得到undefined值
var a = 100;
console.log(b); // 报错:b is not defined ===> 找不到b这个变量
let b = 10;
console.log(c); // 报错:c is not defined ===> 找不到c这个变量
const c = 10;
var声明变量存在变量提升,let和const不存在变量提升(函数及变量的声明都将被提升到函数的最顶部 变量可以在使用后声明,也就是变量可以先使用再声明)
function fn1() {
//var a
if (true) {
console.log(a + ' now')
}
else {
var a = 1
console.log(a)
}
}
fn() // a -> undefined
//if(false) ----> a -> 1
a被定义在else中,但是变量的申请会提升到顶部,所以if语句中得到的a是undefined(已经被声明但是没有赋值), 当进入else中后a读取的是被赋值后的值
let const块级局部变量
function fun1() {
// console.log(a) //undefined
// console.log(b,c) b,c is not defined
if(true){
console.log(b) //Uncaught ReferenceError: Cannot access 'b' before initialization
var a = 1;
let b = 2
const c = 3;
}
console.log(a) //1
// console.log(b,c) b,c is not defined
}
fun1()
在代码块块调用let const会报错,表明let ,const声明的变量只在它所在的代码块有效,不存在变量提升
let/const
命令会使区块形成封闭的作用域。若在声明之前使用变量,就会报错。
在代码块内,使用 let
命令声明变量之前,该变量都是不可用的。
这称为 “暂时性死区”
用在循环中
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
使用let定义i,得到的结果为6,let声明,当前的i
只在本轮循环有效,所以每一次循环的i
其实都是一个新的变量
用var声明的i在循环内一直指向的是全局的i,导致运行时输出的是最后一轮的i
的值
const 声明一个只读的常量
const a;
console.log(a) //Uncaught SyntaxError: Missing initializer in const declaration const声明中缺少初始化
const a = 1;
a = 2; // caught TypeError: Assignment to constant variable. 对常量变量的赋值
//const一旦声明变量,就必须立即初始化,不能留到以后赋值
var a = "a";
let b = 25;
// 以下两行都会报错 caught SyntaxError: Identifier 'a' has already been declared
//let,const不可重复声明
const a = "a";
const b = 30;
const
并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const
只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123; //123
// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only
常量foo
储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo
指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。
const a = [];
a.push('1'); // 可执行
a.length = 0; // 可执行
a = ['2']; // 报错
常量a
是一个数组,这个数组本身是可写的,但是如果将另一个数组赋值给a
,就会报错
关于引用类型赋值传值和传址问题 https://blog.csdn.net/lanseguhui/article/details/110493053?spm=1001.2014.3001.5501