Javascript原型常量声明
我正在使用RESTful API,我的Javascript代码通过jQuery的$.ajax()调用进行REST查询 我已经实现了一个javascript Rest类,我将在下面展示它(大大简化): 代码按预期工作,但是我决定添加一些常量来帮助美化代码并提高可读性。例如,我在代码中有几个地方检查xhr.status==200或xhr.status==400等等 我可以将类变量声明为Javascript原型常量声明,javascript,oop,Javascript,Oop,我正在使用RESTful API,我的Javascript代码通过jQuery的$.ajax()调用进行REST查询 我已经实现了一个javascript Rest类,我将在下面展示它(大大简化): 代码按预期工作,但是我决定添加一些常量来帮助美化代码并提高可读性。例如,我在代码中有几个地方检查xhr.status==200或xhr.status==400等等 我可以将类变量声明为Rest.prototype.STATUS\u OK=200 但变量是可编辑的,我想不出如何使它们保持不变。例如,在
Rest.prototype.STATUS\u OK=200代码>
但变量是可编辑的,我想不出如何使它们保持不变。例如,在我的代码中,我可以做一个this.STATUS\u OK=123代码>,这将修改变量。我一直在玩const关键字,运气不好
我看到了这一点,但没有多大帮助
有人能告诉我如何使这些字段成为常量而不是变量吗?这在Javascript中是不可能的。您可能能做的最好的事情是创建一些类似闭包的东西:
var StatusCode = (function() {
var STATUS_OK = 200,
STATUS_BAD_REQUEST = 400;
return {
getOk: function() {
return STATUS_OK;
},
getBadRequest: function() {
return STATUS_BAD_REQUEST;
}
}
});
然后像StatusCode.getOk()==200那样使用它。这将帮助您无法更改这些“常量”,但也会对您的可读性造成不利影响(这可能是基于观点的)。
我只会将这些常量保留为大写,以将它们标记为常量,尽管它们可以更改。您可以将状态定义为getter,但这在IE8及更早版本中不起作用
var Rest = function (baseUrlPath, errorMessageHandler) {
this.STATUS_OK = 123; // trying to override.
};
// Declare HTTP response codes as constants
Rest.prototype = {
get STATUS_OK(){ return 200; },
get STATUS_BAD_REQUEST(){ return 400; }
}
var client = new Rest();
console.log( client.STATUS_OK ); // 200!
client.STATUS_OK = 123;
console.log( client.STATUS_OK ); // still 200!
关于getter和setter的更多信息:使用ECMAScript 5,可以使值不可设置:
Object.defineProperty(Rest, "STATUS_OK", {
enumerable: false, // optional; if you care about your enumerated keys
configurable: false,
writable: false,
value: 200
});
或者,由于这些是默认值,只需执行以下操作:
Object.defineProperty(Rest, "STATUS_OK", { value: 200 });
这使得Rest.STATUS\u OK
在访问时产生200
,但它不会响应重新定义它或删除它的尝试。此外,configurable:false
将阻止任何使用后续的defineProperty
调用重新定义属性的尝试
但是,这在(尤其是IE8及以下版本)中不起作用。Javascript不支持创建不可变常量。
即使是关键字也不推荐,因为它在某些浏览器中不起作用
我认为最好的方法是使用Object.freeze
:
Rest.Status = {};
Rest.Status.Ok = "Ok";
Object.freeze(Rest.Status);
Object.freeze将忽略状态对象中的更改。
举例来说:
Rest.Status.Ok = "foo";
Rest.Status.Ok; //=> "Ok"
但只需在ECMAScript 5或更高版本中工作即可
在上面,我将status放在status
对象中,我认为它比prototype
更有趣,因为prototype更接近实例方法、属性等。
状态对象看起来像一个枚举。+1;此外,没有理由不能简单地用function(){return“something”;}
@apsillers覆盖getOk
,这是一个很好的观点。作为底线,您无法安全地保护javascript中的任何内容。典型示例-甚至可以覆盖未定义的。Object.defineProperty(Rest.prototype,“STATUS_OK”,{get:function(){return 123;}})这是一个很好的解决方法,但要设置一个常量,必须编写几行代码(我知道它的一条语句,但为了可读性,仍然需要几行代码)似乎是一个难题。当你有很多常数要声明时,肯定会有很多工作要做。随着IE8及以下版本的逐步淘汰,将来可能会有更好的支持。@Husman:实际上,除了值
,您可以省略所有行,因为false
是这些行的默认值。@Bergi Good call;我根据你的建议编辑了我的答案。@Bergi看起来仍然像个黑客,考虑到你必须调用全局对象和defineProperty,然后传入你的对象、变量和你想要设置的属性。大多数语言都有“var x”和“const x”或类似的东西,如final(java)或#define(C/C++),我将选择这作为公认的答案,因为作者和@Bergi都提出了一些很好的建议,但是这在此时对我来说是不可用的,因为代码是针对公司客户机的,IE支持是必须的。谢谢大家的帮助。请注意“字段”是属性,不是变量。对于变量,只需在支持的地方使用。但无论如何,您都会对其进行局部作用域:-)请注意,这仍然允许将Rest.Status
属性重新分配给一个完全不同的对象。是的,我没有意识到这一点。一种替代方法是创建RestStatus对象,但这种方法将存在两个全局变量:(
Rest.Status.Ok = "foo";
Rest.Status.Ok; //=> "Ok"