声明
var + 变量名 = 值。
const+ 常量名 = 值。
let + 变量名 = 值。
声明技巧
多个变量的不同值
var a = 1, b = 2, c = 3
多个变量的相同值
var = a = b = c = 1;
变量提升
var 存在变量提升
变量提升 就是 把var定义内容的过程向上移动,函数自身整体也存在提升。
console.log(a); // 会显示undefined 定义了但没有赋值 var a = 24; 变量提升后 var; console.log(a); a = 4;
let不存在变量提升
console.log(a); // 会报错 显示未定义 let a = 24;
重复声明
var
可以进行多次重复定义并赋值,还可以后定义。
var a = 5; var a = 28;//第二次重新定义并赋值 console.log(a); // 28
function func(a) { var a = 1; //后用var定义a console.log(a); // 1 } func(24);
let
let不允许重复定义,但可以多次赋值,let必须先定义声明 后使用。
let a = 10; let a = 14; console.log(a); // 报错 let a = 10; a = 14; console.log(a); //14
function func(a) { let a = 1; console.log(a); // 报错 不可以后定义 } func(24);
const
const不允许重复声明 或赋值
const a = 1; a = 2;//报错不允许二次赋值 const a ;//报错 同样不允许重新定义
临时性死区
只要作用域内存在 let、const,它们所声明的变量或常量就自动 “绑定” 这个区域,不再受到外部作用域的影响。
let a = 2; //在相同作用域下 不允许二次let声明 function func() { console.log(a); // 报错 let a = 1; //在作用域中出现了 let const声明 会将这个变量绑定到函数中,阻碍外部同名变量进入,会往上寻找,变量,但不会跳出函数。 } func();
使用 let 定义变量 务必要先定义后使用
定义函数作用域问题
相同点
访问外部全局变量
var a = "xiao xie"; function func() { console.log(a); } func(); console.log(a); const b = "xiao xie"; function func1() { console.log(b); } func1(); console.log(b); let c = "xiao xie"; function func2() { console.log(c); } func2(); console.log(c);
编辑
都可以在函数内部 访问外部变量(没产生暂时性死区)
重新声明变量
var a = "xiao xie"; function func() { var a = "xiao xie000"; console.log(a); } func(); console.log(a);
编辑
在函数内部重新定义并赋值了a,相当于重新开了一块儿内存,这个时候就存在了两个a
所以打印了两个不相同的值
不重新声明
var a = "xiao xie"; function func() { a = "xiao xie000"; console.log(a); } func(); console.log(a);
编辑
在函数内部 不声明直接赋值 会修改原来a地址的值。所以打印了两个相同的值。如果在全局范围内找不到同名变量,自身则就变成了一个全局变量a(全局污染问题)。
也就是说 变量在内部声明 是私有的 在内部不声明则是全局的,(共同点)
全局污染问题
上面已经提到过了这个问题,在实际开发中,我们应该严格遵守代码规范,不能图方便,不要不声明变量,就直接使用,不然会在后续书写问题引发安全隐患,为了避免问题,可以开启严格模式进行书写提示。
"use strict"; function func() { a = "xiao xie000"; console.log(a); } func(); console.log(a);
编辑
由于a没有定义 所以会报错 使用了 "use strict"; 严格模式后,就可以避免这种代码规范问题。
块级作用域
var a = 8; for (var a = 0; a < 3; a++) { console.log(a); } console.log(a);
编辑
var 没有块级作用域,所以会覆盖原来a变量的内容。
let a = 8; for (let a = 0; a < 3; a++) { console.log(a); } console.log(a);
编辑
外面的a 没有被影响 任然原样进行输出。
除了函数和对象的以外的{}都是块级作用域
常量的知识点
我们之前说了 常量实不允许二次定义和赋值的,不过并不是所有的地方都不可以。
其实常量不能重新赋值,指的是不能改变指定的内存地址,我们可以使用引用,改变引用里的其他东西
比如说对象里的键名键值,或者是数组同样可以改变。
const a = {}; a.b = [5, 4, 3, 2, 1]; console.log(a);
编辑
在不同作用域中,我们可以进行同名常量的声明。
const a = [5, 4, 3, 2, 1]; { const a = [5, 4, 3, 2, 1]; }
引用类型 只要内存地址不变 我们可以改值,在不同作用域中可以进行重复定义、
var全局污染
当我们使用var定义全局变量时,会产生全局污染,这是var声明关键字本身的一个大问题,
全局污染是这样的
var screenLeft = 0 console.log(window.screenLeft);
编辑
它会影响window对象里的关键字效果。使用let则不会影响
let screenLeft = 0 console.log(window.screenLeft);
编辑