var let const 定义方式比较
Node.js var let const 定义方式比较
Categories:
定义方式
定义方式 | 说明 |
---|---|
const | 不会被重新指定值的变数 e.g. const PI = 3.14159 |
let | 在指定区块才有效用的变数 |
var | 在整个函式或区块中皆可以取用 |
var
在 function 外的 var 可以被 function 取用
var my_name = "KJ";
function sayMyName() {
// KJ
console.log(my_name);
}
sayMyName();
在 function 内的 var 无法被外面取用
function defineMyName() {
var my_name = "KJ";
}
// my_name is not defined
console.log(my_name);
同样变数 可以
重新定义
不建议使用,会导致变数定义混乱
var my_name = "Kay";
var my_name = "Jay";
// Jay
console.log(my_name);
let
在 function 内的 let 无法被外面取用
function defineMyName() {
let my_name = "KJ";
}
// my_name is not defined
console.log(my_name);
内部变数与外部变数名称一样不会互相汙染
let my_name = "Kay";
if (true) {
let my_name = "Jay";
// Jay
console.log(my_name);
}
// Kay
console.log(my_name);
同样变数无法重新定义
let my_name = "Kay";
// SyntaxError: Identifier 'my_name' has already been declared
let my_name = "Jay";
const
常数无法重新被赋予值
const my_name = "Kay";
my_name = "Jay";
// TypeError: Assignment to constant variable.
console.log(my_name);
const employee = {
name: "Kay",
age: 18
};
// TypeError: Assignment to constant variable.
employee = {
name: "Jay",
age: 17
}
常数物件数值可以被异动
const employee = {
name: "Kay",
age: 18
};
// { name: 'Kay', age: 18 }
console.log(employee);
// 变更常数物件数值
employee.name = "Jay";
employee.age = 17;
// { name: 'Jay', age: 17 }
console.log(employee);
同样变数无法重新定义
const my_name = "Kay";
// SyntaxError: Identifier 'my_name' has already been declared
const my_name = "Jay";
必须赋予初始值
// SyntaxError: Missing initializer in const declaration
const my_name;
var vs let vs const
类型 | var | let | const |
---|---|---|---|
scope 范围 | global 全域 | block 区块 | block 区块 |
re-declared 重新定义 | 可 | X | X |
update 更新 | 可 | 可 | X |
赋予初始值 | 不限制 | 不限制 | 必要 |
function run() {
var my_name = "Kay";
let my_age = 19;
// Kay 19
console.log(my_name, my_age);
{
var their_name = "Jay"
let their_age = 17;
// Jay 17
console.log(their_name, their_age);
}
// Jay
console.log(their_name);
// ReferenceError: their_age is not defined
console.log(their_age);
}
run();
赋予值异动
var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
// and store them in funcs
funcs[i] = function() {
// each should log its value.
console.log("My var value: " + i);
};
}
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j]();
}
// My var value: 3
// My var value: 3
// My var value: 3
var i
最后已经变成 3 了,所以最后会印出三行 My var value: 3
var funcs = [];
// let's create 3 functions
for (let i = 0; i < 3; i++) {
// and store them in funcs
funcs[i] = function() {
// each should log its value.
console.log("My let value: " + i);
};
}
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j]();
}
// My let value: 0
// My let value: 1
// My let value: 2
let i
只作用在 for 的 scope 中,所以最后会分别印他们当初传进去的值
经典问题
Scope 数值
var a = 1;
var b = 1;
var e = 1;
function test(a) {
// undefined
console.log(a);
var b = 2;
// 2
console.log(b);
if (true) {
let c = 5;
var d = 6;
const e = 7;
}
// undefined
console.log(c);
// 6
console.log(d);
// 1
console.log(e);
}
test();
i
执行到后面已经变成 6 了,然后接下来会执行 setTimeout
的程式,印出来的变数都是 6
for(var i = 1; i <= 5; i++) {
setTimeout(function() {
console.log(i)
}, 0)
}
// 6
// 6
// 6
// 6
// 6
解决方式
使用 let
将变数定在 block 中,区块中会保留原本的数值
// 方法 1
for(let i = 1; i <= 5; i++) {
setTimeout(function() { console.log(i) }, 0)
}
// 1
// 2
// 3
// 4
// 5
使用 IIFE 方式,事先将要处理的变数传入会立即执行的函式,将变数包在 block 中,这样执行的时候也可以拿到正确的值
// 方法 2 IIFE
for(var i = 1; i <= 5; i++) {
(function (x) {
setTimeout(function() { console.log(x) }, 0)
})(i)
}
// 1
// 2
// 3
// 4
// 5