在JavaScript中没有常量,通常在许多现代环境中可能会给你提供一个const语句去创建一个常量。
一种解决办法,一个常见的解决办法就是使用命名规范,让不应该被改变的变量名称全部大写。
这个命名规范在JavaScript内置对象身上就被使用:
Math.PI; // 3.141592653589793 Math.SQRT2; // 1.4142135623730951 Number.MAX_VALUE; // 1.7976931348623157e+308对于你自己的常量,你可以使用相同的命名规范并将它们作为构造方法的静态属性:
// constructor var Widget = function () { // implementation... }; // constants Widget.MAX_HEIGHT = 320; Widget.MAX_WIDTH = 480;相同的命名规范也可以在使用对象字面量创建对象时使用;这个常量可以是拥有大写名称的普通属性。
如果你真的想要一个不可变的值,你可以创建一个private属性并提供getter方法,但没有setter方法。
当你可以通过简单的命名规范实现的时候,这在大多数情况下可能是多余的,但它仍然是一个选项。
下面这个例子是一种多功能常量对象(constant object)的实现,对象提供这些方法
set(name, value) 定义一个常量
isDefined(name) 检查常量是否存在
get(name) 获取一个常量的值
在这个实现中,只有原始类型( primitive values)被允许作为常量。
也采用了一些额外的检查,确保声明常量的名字恰巧和内置属性的名字是一样时依旧是好的,比如:toString或hasOwnProperty。
通过hasOwnProperty()检查和给所有的常量名添加一个额外的自动生成的前缀:
var constant = (function () { var constants = {}, ownProp = Object.prototype.hasOwnProperty, allowed = { string: 1, number: 1, boolean: 1 }, prefix = (Math.random() + "_").slice(2); return { set: function (name, value) { if (this.isDefined(name)) { return false; } if (!ownProp.call(allowed, typeof value)) { return false; } constants[prefix + name] = value; return true; }, isDefined: function (name) { return ownProp.call(constants, prefix + name); }, get: function (name) { if (this.isDefined(name)) { return constants[prefix + name]; } return null; } }; }());测试这个实现:
// check if defined constant.isDefined("maxwidth"); // false // define constant.set("maxwidth", 480); // true // check again constant.isDefined("maxwidth"); // true // attempt to redefine constant.set("maxwidth", 320); // false // is the value still intact? constant.get("maxwidth"); // 480