如何使用const关键字创建Javascript常量作为对象的属性?

dan*_*oon 42 javascript const properties object

为什么不能将常量设置为变量本身的对象的属性?

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
Run Code Online (Sandbox Code Playgroud)

为什么通过引用传递的常数突然变得可变?编辑:我知道应用程序不会(或者更确切地说......)不可变; 这只是一个观察......

(function() {
    const App;
    // bunch of code
    window.com_namespace = App;
}());
window.com_namespace; // App
window.com_namespace = 'something else';
window.com_namespace; // 'something else'
Run Code Online (Sandbox Code Playgroud)

如何使用这些限制来构建一个包含常量的组织良好,可扩展,面向对象的单一命名空间的库?

编辑:我相信zi42,但我只想问为什么

zia*_*aab 53

你不能用常数来做.执行行为与您想要的行为但不使用常量的唯一可行方法是定义不可写属性:

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

关于为什么const传递给函数变为变量的问题,答案是因为它是通过值而不是通过引用传递的.该函数获取一个与常量具有相同值的新变量.

编辑:感谢@pst注意到javascript中的对象文字实际上并没有"通过引用传递",而是使用call-by-sharing:

虽然这个术语在Python社区中有广泛的用法,但是其他语言(如Java和Visual Basic)中的相同语义通常被描述为call-by-value,其中值隐含为对象的引用.

  • 不是.对象不是*"通过引用传递"(这是一个模糊的短语).实现通常"通过引用的*值*"但重要的是JavaScript具有[按对象共享语义调用](http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing).有趣的事实:*ECMAScript规范不使用术语"参考"*. (7认同)
  • @pst-术语"引用"绝对**是**使用:[引用类型](http://es5.github.com/#x8.7)是一个规范工件来解释(除其他外)如何价值分配有效.甚至有声明"允许函数调用返回引用". (5认同)

zlo*_*ctb 7

const person = {
    name: "Nicholas"
};

// works
person.name = "Greg";



console.log(person) //Greg 
Run Code Online (Sandbox Code Playgroud)

这就是使用Object.defineProperty的原因


小智 6

有一种简单得多的方法可以做到这一点。我喜欢这种模式。简单对象。

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"
Run Code Online (Sandbox Code Playgroud)

Object.freeze在这里工作

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze

如果需要,可以通过将静态属性保留在构造函数上的对象字面量返回值上,从而将静态属性保留在实例之外。

const只会使其成为只读引用。分配后,就像这里在对象常量中一样,它成为已构造对象的属性。


Con*_* DO 5

var obj = {};
Object.defineProperty( obj, "MY_FAKE_CONSTANT", {
  value: "MY_FAKE_CONSTANT_VALUE",
  writable: false,
  enumerable: true,
  configurable: false // instead of true
});
Run Code Online (Sandbox Code Playgroud)

我们还应该将configurable设置为false,以防止从obj中删除该属性。

delete obj.MY_FAKE_CONSTANT;
Run Code Online (Sandbox Code Playgroud)

随着可配置true,在此行之后,我们不再拥有MY_FAKE_CONSTANT

参考