const foo = {
};
// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123
// 将 foo 指向另一个对象,就会报错
foo = {
}; // TypeError: "foo" is read-only
上記のコードでは、定数 foo にオブジェクトを指すアドレスが格納されます。このアドレスのみが不変です。つまり、foo が別のアドレスを指すことはできませんが、オブジェクト自体は変更可能であるため、新しい属性を追加することができます。
以下に別の例を示します。
const a = [];
a.push('Hello'); // 可执行
a.length = 0; // 可执行
a = ['Dave']; // 报错
上記のコードでは、定数 a は配列であり、配列自体は書き込み可能ですが、別の配列が a に代入されるとエラーが報告されます。
本当にオブジェクトをフリーズしたい場合は、Object.freeze メソッドを使用する必要があります。
const foo = Object.freeze({
});
// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;
上記のコードでは、定数 foo がフリーズされたオブジェクトを指しているため、新しいプロパティの追加は機能せず、厳密モードではエラーが報告されます。
オブジェクト自体をフリーズするだけでなく、オブジェクトのプロパティもフリーズする必要があります。以下はオブジェクトを完全にフリーズする関数です。
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) => {
if ( typeof obj[key] === 'object' ) {
constantize( obj[key] );
}
});
};