我试图弄清楚是否有办法在其原型中定义一个对象属性作为动态值,每次创建对象的实例时都可以更改。这是我描述它的最佳方式;我已经做了一个小提示来展示我正在尝试做什么(虽然它不起作用)。
var Response = {
LCID: 321
};
Date.prototype.LCID = Number(0);
Date.prototype.LCID.valueOf = function() { return Response.LCID; };
document.write((new Date()).LCID);
Response.LCID = 456;
document.write((new Date()).LCID);
我想要实现的是Response.LCID
可以在代码的生命周期中发生变化,因为您可以看到我稍后在代码中更改其值。每当我创建Date
对象时,我希望(new Date()).LCID
的值为Response.LCID
的当前值,而不仅仅是我第一次创建Date.prototype.LCID
时的值。
有什么办法可以做到吗?最大的限制是它必须在JavaScript 1.5中工作......虽然我很想知道它是否可以在最近的版本中完成。
答案 0 :(得分:1)
好的,这是使用__defineGetter__
方法,但是我不确定它将如何在所有浏览器上运行,但是我能找到实现你想要的唯一方法(我想这次是什么你想要的)
http://jsfiddle.net/tx2fW/6/工作示例。
var Response = {
LCID: 321
};
var d = Date.prototype;
d._LCID = Number(0);
d.getLCID = function() {
if (d._LCID != Response.LCID) d._LCID = Response.LCID;
return d._LCID ;
};
d.__defineGetter__("LCID", function() {
return this.getLCID();
});
document.write((new Date()).LCID);
Response.LCID = 456;
document.write((new Date()).LCID);
有关__defineGetter__
的替代方案,请参阅this post
答案 1 :(得分:1)
Number(0) === 0
。修改原始值的.valueOf
和.toString
无效。
执行此操作的正确方法是使用new
operator传递 {/ 1}}构造函数的实例:
Number
var Response = {
LCID: 321
};
Date.prototype.LCID = new Number(); // <-- Use the "new" operator
Date.prototype.LCID.valueOf = function() { return Response.LCID; };
是一个对象。的 LCID
即可。typeof new Date().LCID === 'object'
是LCID
的真实实例。的 Number
强> new Date().LCID instanceof Number === true
等于321: LCID
(new Date().LCID == 321) === true
与321不同: LCID
(因为LCID是一个对象,而321是一个原始数值)。 PS。如果您不熟悉(new Date().LCID === 321) === false
与==
,请参阅Which equals operator (== vs ===) should be used in JavaScript comparisons?
答案 2 :(得分:0)
经过一些研究和实验,我能够真正解决问题。我曾尝试使用Date构造函数等等,但我在初始试验中没有太多运气 - 显然是因为我忽略了Date对象的独特之处,因为它的功能不同取决于它的调用方式(如函数或对象构造函数)。这意味着您不能只执行Date.prototype.constructor.apply(this, arguments)
,因为您将获得的所有内容都是一个字符串(Date对象被称为函数)。
找到this thread并阅读之后,我想出了以下代码,它创建了一个实际的Date对象(或者作为函数调用的字符串),并完美地模仿了内置的Date对象(至于我的测试显示无论如何)。每次创建一个新的Date对象时,它都会获得LCID属性,该属性是在对象创建过程中动态生成的,这正是我所需要的。
Date = (function(orig) {
var date = function(a, b, c, d, e, f, g) {
var object = (this instanceof Object ? (arguments.length < 1 ? new orig() : (arguments.length < 2 ? new orig(a) : (arguments.length < 4 ? new orig(a, b || 0, c || 1) : new orig(a, b, c, d || 0, e || 0, f || 0, g || 0)))) : orig());
object.LCID = Response.LCID;
return object;
};
date.prototype = orig.prototype;
return date;
})(Date);
我还创建了一堆测试用例,以确保与内置Date对象没有区别,或使用此代码(注释掉此代码以使用内置Date对象查看结果并进行比较)。
var Response = { 'LCID': 123 };
Date = (function(orig) {
var date = function(a, b, c, d, e, f, g) {
var object = (this instanceof Object ? (arguments.length < 1 ? new orig() : (arguments.length < 2 ? new orig(a) : (arguments.length < 4 ? new orig(a, b || 0, c || 1) : new orig(a, b, c, d || 0, e || 0, f || 0, g || 0)))) : orig());
object.LCID = Response.LCID;
return object;
};
date.prototype = orig.prototype;
return date;
})(Date);
var x = new Date();
document.writeln(x);
document.writeln(x.LCID);
document.writeln(x.getFullYear());
document.writeln(typeof x);
document.writeln(Object.prototype.toString.call(x));
document.writeln(x instanceof Date);
document.writeln("<br/>");
Response.LCID = 456;
var y = new Date();
document.writeln(y);
document.writeln(y.LCID);
document.writeln(y.getFullYear());
document.writeln(typeof y);
document.writeln(Object.prototype.toString.call(y));
document.writeln(y instanceof Date);
document.writeln("<br/>");
document.writeln(Date());
document.writeln(new Date());
document.writeln(new Date(2012));
document.writeln(new Date(2012, 7));
document.writeln(new Date(2012, 7, 14));
document.writeln(new Date(2012, 7, 14, 9));
document.writeln(new Date(2012, 7, 14, 9, 45));
document.writeln(new Date(2012, 7, 14, 9, 45, 27));
document.writeln(new Date(2012, 7, 14, 9, 45, 27, 687));
这也是一个更新的小提琴:http://jsfiddle.net/tx2fW/9/