首先,我将您的问题分解为两个单独的问题:
- 如何从静态属性(常量或其他)设置实例属性
- 如何创建方便的常量属性(无论是实例化的还是静态的)
由于 JS 和 Java 之间的架构差异,无论你做什么,它都会有点难看。
静态属性
这里的关键是您必须延迟访问静态变量的尝试,直到实际创建实例。我不知道 mootools(是initialize
吗?),但在 Dojo 1.9 中,相关方法被称为constructor
,所以这就是我将在本示例中使用的方法:
var makeMyClass = function(){
var clazz = new Class ({
instanceVal : null, // Don't know what to put here yet
constructor : function(){
/*
I know this looks weird that this property is ALSO
called "constructor", but it works in Dojo 1.9. Consult
your debugger to see if a similar tactic works in mootools.
*/
var selfClass = this.constructor;
// Remember that if staticVal is an object, you may-or-may-not want an independent copy
this.instanceVal = selfClass.staticVal;
}
});
clazz.staticVal = "Hello World";
return clazz;
};
var com.example.myClass = makeMyClass();
现在,如果您修改com.example.myClass.staticScalarVal
它应该会影响将来构建的类,尽管 IMO 构建器或工厂设计模式会好得多。
常数
这里的实现很大程度上取决于你想变得多么僵硬/偏执,因为 JS 自然对动态变化非常宽容。所以这里只是一些开始的想法:
由访问器方法保护的常量
如果您想在访问未定义的常量时抛出错误(而不是undefined
在 15 步后返回并使其失败),请考虑:
var createLightweightConstantHolder = function(){
// Because it's nestled in this method, we're protected from the evil outside world.
var constants = {
FOO : "hello",
BAR : [1,2,3]
};
return function(cname){
if(typeof cname == "undefined"){
// Gives all constants back at once, in case someone needs to iterate
return lang.clone(constants);
}else{
// Value of a particular thing
if(constants.hasOwnProperty(cname)){
return constants[cname];
}else{
throw "Constant '"+cname+"' does not exist.";
}
}
}
};
var stuff = createLightweightConstantHolder();
stuff("FOO"); // Returns "hello"
stuff("BAZ"); // Throws a descriptive exception
var copyOfUnderlyingValues = stuff();
这有点难看,因为您将常量名称作为字符串传递,但它确实会快速失败并阻止修改。
常量使用Object.freeze
这一个使用“冻结”对象的相对较新的功能。请注意,它仅冻结顶级对象以防止添加/删除/替换值。仍然可以更改非标量。
var constants = {
FOO : "hello",
BAR : [1,2,3],
BAZ : {"x","y"}
};
constants = Object.freeze(constants);
/*
* Some things which do/don't work:
*/
constants.FOO; // Is "hello"
constants.FOO = "goodbye"; // Won't change. Depending on env and strict-mode, may throw an error or else silently fail.
constants.OOPS; // Is undefined, does NOT throw an error when access it.
constants.BAR.push(4); // DOES alter array items
constants.BAZ.x = "z"; // DOES alter object properties
这并非在所有平台上都可用,请查看浏览器/环境兼容性图表。