なぜ変数自体であるオブジェクトのプロパティとして定数を設定できないのですか?
const a = 'constant' // all is well
// set constant property of variable object
const window.b = 'constant' // throws Exception
// OR
var App = {}; // want to be able to extend
const App.goldenRatio= 1.6180339887 // throws Exception
そして、参照によって渡された定数が突然変数になるのはなぜですか?編集:私はアプリが変更可能でないことを知っています(むしろ...する必要はありません)。これは単なる観察です...
(function() {
const App;
// bunch of code
window.com_namespace = App;
}());
window.com_namespace; // App
window.com_namespace = 'something else';
window.com_namespace; // 'something else'
これらの制限で、定数を含む、うまく整理された、拡張可能な、オブジェクト指向の、単一の名前空間ライブラリをどのように作成できますか?
編集:私はzi42を信じていますが、私はただ尋ねる必要があります なぜ
定数ではできません。あなたが望むように振る舞うが定数を使用しない何かをする唯一の可能な方法は、書き込み不可能なプロパティを定義することです:
var obj = {};
Object.defineProperty( obj, "MY_FAKE_CONSTANT", {
value: "MY_FAKE_CONSTANT_VALUE",
writable: false,
enumerable: true,
configurable: true
});
関数に渡されるconst
が変数になる理由に関する質問については、参照ではなく値で渡されるためです。関数は、定数と同じ値を持つ新しい変数を取得しています。
edit:JavaScriptのオブジェクトリテラルは実際には「参照渡し」ではなく、 call-by-共有 :
この用語は、Pythonコミュニティで広く使用されていますが、JavaやVisual Basicなど、他の言語の同一のセマンティクスは、値渡しと呼ばれます。ここで、値はオブジェクトへの参照であると暗示されています。
const person = {
name: "Nicholas"
};
// works
person.name = "Greg";
console.log(person) //Greg
それがObject.definePropertyを使用する理由です
これを行うには、はるかに簡単な方法があります。私はこのパターンが好きです。シンプルなオブジェクト。
window.Thingy = (function() {
const staticthing = "immutable";
function Thingy() {
let privateStuff = "something";
function get() {
return privateStuff;
}
function set(_) {
privateStuff = _;
}
return Object.freeze({
get,
set,
staticthing
});
}
Thingy.staticthing = staticthing;
return Object.freeze(Thingy);
})();
let myThingy = new Thingy();
Thingy.staticthing = "fluid";
myThingy.staticthing = "fluid";
console.log(Thingy.staticthing); // "immutable"
console.log(myThingy.staticthing); // "immutable"
Object.freezeはここで作業を行っています
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
必要に応じて、コンストラクター関数のオブジェクトリテラルリターンから静的プロパティを除外することで、インスタンスから静的プロパティを除外できます。
constは、読み取り専用の参照のみにします。ここにオブジェクトリテラルのように割り当てると、構築されたオブジェクトのプロパティになります。
var obj = {};
Object.defineProperty( obj, "MY_FAKE_CONSTANT", {
value: "MY_FAKE_CONSTANT_VALUE",
writable: false,
enumerable: true,
configurable: false // instead of true
});
また、configurableをfalseに設定して、プロパティが削除されないようにする必要がありますobj
delete obj.MY_FAKE_CONSTANT;
configurableをtrueにすると、行の後には、MY_FAKE_CONSTANTもう。
const宣言 「値への読み取り専用参照を作成します。保持する値が不変であることを意味するのではなく、変数識別子を再割り当てできないことを忘れないでください」
Constキーワードは「let」と同様に機能するため、他のブロックで再宣言できます。
const MyConst = 5;
console.log('global MyConst =', MyConst); //global MyConst = 5
if(true){
const MyConst = 99
console.log('in if block, MyConst =', MyConst); //in if block, MyConst = 99
}
console.log('global MyConst still 5 ?', MyConst===5); //global MyConst still 5 ? true
オブジェクトプロパティが定数のように振る舞うよりも必要な場合は、@ ziad-saabのように、書き込み不可のプロパティとして定義する必要があります。
定数がオブジェクトであり、プロパティが変わらない場合は、 Object.freeze() を使用してオブジェクトを不変にします。
(function(){
var App = { };
// create a "constant" object property for App
Object.defineProperty(App , "fixedStuff", {
value: Object.freeze({ prop:6 }),
writable: false,
enumerable: true,
configurable: true
});
Object.defineProperty(window, "com_namespace", {
value: App,
writable: false,
enumerable: true,
configurable: true
});
})()
com_namespace.newStuff = 'An extension';
com_namespace.fixedStuff.prop = 'new value'; // do nothing!
console.log(com_namespace.fixedStuff.prop); //6
Object.definePropertyのconfigurable:falseおよびwritable:falseを作成するプロパティで定数を定義する必要があると考えています。
例:Object.definePropertyでconfigurable:trueを設定した場合
cosnt obj = {name: 'some name'};
Object.defineProperty(obj, 'name', {
enumerable: true,
configurable: true,
writable: false
});
これでobj.nameを 'constant'にしていますが、できた後は
Object.defineProperty(obj, 'name', {
enumerable: true,
configurable: true,
writable: true // <-- you can set to true because configurable is true
})
ただし、設定可能をfalseに設定すると、書き込み可能なプロパティを編集できなくなります。
Object.defineProperty(obj, 'name', {
enumerable: true,
configurable: false, // <-- with this you never could edit writable property
writable: false
})
そして、すべてのプロパティに対してObject.freezeを使用できます
Object.freeze(obj);
Object.freezeは列挙可能なプロパティのみを反復処理します