动态JavaScript对象属性值

时间:2012-04-15 08:38:35

标签: javascript asp-classic jscript

我试图弄清楚是否有办法在其原型中定义一个对象属性作为动态值,每次创建对象的实例时都可以更改。这是我描述它的最佳方式;我已经做了一个小提示来展示我正在尝试做什么(虽然它不起作用)。

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);

http://jsfiddle.net/tx2fW/2/

我想要实现的是Response.LCID可以在代码的生命周期中发生变化,因为您可以看到我稍后在代码中更改其值。每当我创建Date对象时,我希望(new Date()).LCID的值为Response.LCID的当前值,而不仅仅是我第一次创建Date.prototype.LCID时的值。

有什么办法可以做到吗?最大的限制是它必须在JavaScript 1.5中工作......虽然我很想知道它是否可以在最近的版本中完成。

3 个答案:

答案 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

带注释的演示和注释:http://jsfiddle.net/tx2fW/7/

  • 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/