JavaScript: 常量属性

12
在JavaScript中,我可以声明对象属性为常量吗?
这是一个示例对象:
   var XU = {
      Cc: Components.classes
   };

或者

   function aXU()
   {
      this.Cc = Components.classes;
   }

   var XU = new aXU();

只是在它前面加上"const"并不起作用。

我知道,我可以声明一个同名的函数(这也算是一种常量),但我正在寻找一种更简单和更易读的方法。

浏览器兼容性并不重要。它只需要在Mozilla平台上工作,因为它是一个Xulrunner项目。

非常感谢!

干杯。

4个回答

12

由于您只需要在Mozilla平台上运行,可以定义一个没有相应setter的getter。对于您的每个示例,最好的方法都是不同的。

在对象字面量中,有一个特殊的语法:

var XU = {
    get Cc() { return Components.classes; }
};
在您的第二个示例中,您可以使用__defineGetter__方法将其添加到aXU.prototype或构造函数内部的this。哪种方式更好取决于对象每个实例的值是否不同。 编辑:为了解决可读性问题,您可以编写像defineConstant这样的函数来隐藏丑陋的代码。
function defineConstant(obj, name, value) {
    obj.__defineGetter__(name, function() { return value; });
}

另外,如果您想在尝试赋值时抛出一个错误,您可以定义一个只会抛出错误对象的 setter:

function defineConstant(obj, name, value) {
    obj.__defineGetter__(name, function() { return value; });
    obj.__defineSetter__(name, function() {
        throw new Error(name + " is a constant");
    });
}

如果所有的实例都有相同的值:

function aXU() {
}

defineConstant(aXU.prototype, "Cc", Components.classes);

或者,如果值取决于对象:

function aXU() {
    // Cc_value could be different for each instance
    var Cc_value = return Components.classes;

    defineConstant(this, "Cc", Cc_value);
}

要了解更多详细信息,您可以阅读Mozilla开发者中心文档


这实际上是我最终所做的,尽管它缺乏可读性。我还定义了一个不执行任何操作的setter。我从另一个线程中得到了这个,但从你的例子中看来,setter似乎并不必要。所以我把它删除了。感谢大家! - CodeSalad
关于可读性的问题,你提出了很好的观点。你可以编写一个defineConstant函数之类的东西来帮助解决这个问题。 - Matthew Crumley
这正是我正在寻找的。非常感谢。我正在使用一个名为GVars的全局变量,它被声明为全局常量。然后,我使用您的函数将getter和setter添加为此GVars的字段。我需要这样做是因为我想创建全局常量,其值在jQuery函数之后分配。这是一个非常出色的解决方案。非常感谢。(如果可以的话,我会给你多于一票。) - NawaMan

5

更新:这个可行!

const FIXED_VALUE = 37;
FIXED_VALUE = 43;
alert(FIXED_VALUE);//alerts "37"

从技术上讲,我认为答案是否定的(直到const进入野外)。您可以提供包装器等,但归根结底,您可以随时重新定义/重置变量值。

我认为最接近的方法是在“类”上定义“常量”。

// Create the class
function TheClass(){
}

// Create the class constant
TheClass.THE_CONSTANT = 42;

// Create a function for TheClass to alert the constant
TheClass.prototype.alertConstant = function(){
  // You can’t access it using this.THE_CONSTANT;
  alert(TheClass.THE_CONSTANT);
}

// Alert the class constant from outside
alert(TheClass.THE_CONSTANT);

// Alert the class constant from inside
var theObject = new TheClass();
theObject.alertConstant();

然而,“类”TheClass本身可以在以后重新定义。

2
如果你在使用JavaScript 1.5 (例如在XUL中),你可以使用const关键字来声明一个常量,而不是用var
但问题在于它不能成为对象的属性。你可以尝试通过将其放在函数内部的命名空间中来限制其作用域。
(function(){ 

const XUL_CC = Components.classes;

// Use the constant here

})()

0

要定义一个常量属性,你可以在defineProperty方法中将writable属性设置为false,如下所示:

代码片段:

var XU = {};

Object.defineProperty(XU, 'Cc', {
    value: 5,
    writable: false
});

XU.Cc = 345;

console.log(XU.Cc);

结果:

5           # The value hasn't changed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接