let 命令
let只在宣告所在的塊級作用域內有效,需要先申明后使用
{
let a = 10;
var b = a;
}
a // ReferenceError: a is not defined
b // 1
var a = [];
for (var i=0;i<10;i++>) {
a[i] = function () {
console.log(i);
}
}
a[6](); // 10
原因:變數i是var命令宣告的,在全域范圍內都有效,全域只有一個變數i,每次回圈,變數i的值都會發生改變,而回圈內被賦給陣列a的函式console.log(i),里面的i指向的是全域i(也就是同一個i,即最后一輪的i的值,也就是10),修改方法var改成let或者將內層函式變成塊級作用域,外層i作為變數值傳給塊級作用域的函式,
const 命令
const宣告一個只讀的常量,一旦宣告變數,就必須立即初始化,不能留到以后賦值,
const foo;
// SyntaxError: Missing initializer in const declaration
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable
const實際上保證的,并不是變數的值不得改動,而是變數指向的那個記憶體地址所保存的資料不得改動,對于簡單資料型別(數值、字符、布林值),值保存在記憶體地址里,對于復雜資料型別(陣列、物件),變數指向的記憶體地址,保存的只是一個指標,const只能保證這個指標是固定的,對于值是否改變不可以保證,
<!-- 物件 -->
const foo = {}
foo.name = 'a'; // 正確
foo = {} // 錯誤
<!-- 陣列 -->
const arr = []
arr.push('a'); // 正確
arr.length = 0; // 可執行
arr = ['a']; // 報錯
如果想讓定義的物件或陣列凍結,可以使用Object.freeze方法,當使用Object.freeze方法凍結物件或陣列時,添加新屬性不起作用,嚴格模式下會報錯,
const foo = Object.freeze({});
// 常規模式時,下面一行不起作用
// 嚴格模式時,報錯
foo.name = 'a';
const arr = Object.freeze([]);
// 常規模式時,下面一行不起作用
// 嚴格模式時,報錯
arr[0] = 'a';
除了將物件本身凍結,物件的屬性也應該凍結,下面是一個將物件徹底凍結的函式,
var constantize = obj => {
Object.freeze(obj);
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object') {
constantize(obj[key]);
}
})
}
const foo = {
name: 'a'
}
foo.age = 20; // 正確
foo.name = 'Lily'; // 正確
constantize(foo);
foo.age = 20; // 報錯
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/108297.html
標籤:JavaScript
