How to create Javascript constants as properties of objects using const keyword?

匿名 (未验证) 提交于 2019-12-03 02:14:01

问题:

How come constants cannot be set as properties of objects which are variables themselves?

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 

And how come constants passed by reference suddenly become variable? EDIT: I know App won't (or rather... SHOULDN'T) be mutable; this is just an observation...

(function() {     const App;     // bunch of code     window.com_namespace = App; }()); window.com_namespace; // App window.com_namespace = 'something else'; window.com_namespace; // 'something else' 

How can a nicely organized, extensible, object-oriented, singly namespaced library containing constants be made with these limitations?

EDIT: I believe zi42, but I just have to ask why

回答1:

You cannot do it with constants. The only possible way to do something that behaves like you want, but is not using constants, is to define a non-writable property:

var obj = {}; Object.defineProperty( obj, "MY_FAKE_CONSTANT", {   value: "MY_FAKE_CONSTANT_VALUE",   writable: false,   enumerable: true,   configurable: true }); 

Regarding your question as to why a const passed to a function becomes variable, the answer is because it's passed by value and not by reference. The function is getting a new variable that has the same value as your constant.

edit: thanks to @pst for noting that objects literals in javascript are not actually "passed by reference", but using call-by-sharing:

Although this term has widespread usage in the Python community, identical semantics in other languages such as Java and Visual Basic are often described as call-by-value, where the value is implied to be a reference to the object.



回答2:

const person = {     name: "Nicholas" };  // works person.name = "Greg";    console.log(person) //Greg  

That's why use Object.defineProperty



回答3:

There is a far simpler way to do this. I like this pattern. Simple Objects.

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 is doing the work here

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze

if you want you can leave the static property off the instance by leaving it off the object literal return on the constructor function.

const will only make it a read-only reference. As soon as you assign it, like here in a object literal it becomes a property of the constructed object.



回答4:

You should not forgot than the const declaration "creates a read-only reference to a value. It does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned"

The const keyword work in a similar way than 'let', so you can redeclare it in an other block

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 

Just like @ziad-saab mantioned if you want an object property than act like a constant, you have to define it as a non-writable property.

if your constant is an object and is property should not change, use Object.freeze() to make the object immutable.

(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 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!