具有内部引用属性的JavaScript对象

时间:2010-09-18 22:31:33

标签: javascript object properties global

我正在尝试创建一个具有一系列“slave”属性的全局对象,这些属性派生自同一对象中一个“master”属性的值 - 如下所示:

var x = 5;
var myObj = {
    master : 17,
    slave1 : this.master + x,
    slave2 : (this.master / 2.2) + 1,
    slave3 : Math.floor(this.slave2)
    //etc.
};

我意识到这是非常错误的,但概念就在那里。我想要做的是更新所有这些'slave'属性,因为myObj.master已更新。最干净的方法是什么?是否需要通过在myObj.master更改时触发的某个事件处理程序显式设置每个从属值...?

6 个答案:

答案 0 :(得分:4)

如果您不是针对Internet Explorer用户,请尝试使用getter和setter。

var x = 5;
function myObj()
{
    this.master = 17;
    this.getSlave1 = function() {return this.master + x;},
    this.getSlave2 = function() {return (this.master / 2.2) + 1;},
    this.getSlave3 = function() {return Math.floor(this.getSlave2());}
}

myObj.prototype = {
    get slave1() {
        return this.getSlave1();
    },
    get slave2() {
        return this.getSlave2();
    },
    get slave3() {
        return this.getSlave3();
    }
};   

行动中:

window.onload = function()
{
    o = new myObj();
    document.write("Master: "+o.master+"</br>");
    document.write("Slave 1: "+o.slave1+"</br>");
    document.write("Slave 2: "+o.slave2+"</br>");
    document.write("Slave 3: "+o.slave3+"</br></br>");
    o.master = 42;
    document.write("Master: "+o.master+"</br>");
    document.write("Slave 1: "+o.slave1+"</br>");
    document.write("Slave 2: "+o.slave2+"</br>");
    document.write("Slave 3: "+o.slave3+"</br>");
}

产生输出:

Master: 17
Slave 1: 22
Slave 2: 8.727272727272727
Slave 3: 8

Master: 42
Slave 1: 47
Slave 2: 20.09090909090909
Slave 3: 20

此代码将从不在过去,现在或将来的任何版本的Internet Explorer中工作。但是,仍然可以使用getSlaveX()函数访问从属值。

答案 1 :(得分:2)

你可能最好使用功能。

var x = 5;
var myObj = {
    master : 17,
    slave1 : function() { return this.master + x },
    slave2 : function() { return (this.master / 2.2) + 1 },
    slave3 : function() { return Math.floor(this.slave2()); }
    //etc.
};

var example = myObj.slave3();

答案 2 :(得分:2)

大卫的答案是一个选项,但是如果你想缓存结果而不是每次重新计算结果,那么反过来一样:

var x = 5;
var myObj = {
    setMaster: function(val) {
        this.master = val;
        this.slave1 = this.master + x;
        // ...
    }
};

myObj.setMaster(17);

答案 3 :(得分:1)

另一种选择可以是使用构造函数来构建你的对象,例如:

var x = 5;

function MyObj(master) {
  this.master = master;
  this.slave1 = this.master + x,
  this.slave2 = (this.master / 2.2) + 1,
  this.slave3 = Math.floor(this.slave2)
}

var myObj = new MyObj(17);

在上面的示例中,我使用master参数和对x全局属性的引用,如果您在该范围内没有x,则还可以提供论证。

您还可以通过几个步骤构建对象:

var myObj = {
    master : 17
}, x = 5;

myObj.slave1 = myObj.master + x;
myObj.slave2 = (myObj.master / 2.2) + 1;
myObj.slave3 = Math.floor(myObj.slave2);

答案 4 :(得分:0)

您不希望公开从属设备并允许它们被设置,因为这会删除它们与master的链接。所以他们应该是私人的。

var x = 5;
var MyObject = function() {
    var master = 17;
    this.setMaster = function(newMaster) {
        master = newMaster;
    };
    this.getMaster = function() {
        return master;
    };
    var slaves = {
        slave1 : function() { return master + x },
        slave2 : function() { return (master / 2.2) + 1 },
        slave3 : function() { return Math.floor(this.slave2()) }
    };
    this.getSlave = function(slave) {
        return slaves[slave]();
    };
};

var o = new MyObject();
o.getSlave("slave1"); // 22
o.getSlave("slave3"); // 8
o.setMaster(3);
o.getSlave("slave1"); // 8
o.getSlave("slave3"); // 2

答案 5 :(得分:0)

您可以使用valueOftoString模拟吸气剂,但它有点笨拙。

function makeValueOf(fn) {
    return {
        valueOf: fn,
        toString: fn
    };
}

function makeObj(master, x) {
    var self = {};

    self.master = master;
    self.slave1 = makeValueOf(function () { return self.master + x; });
    self.slave2 = makeValueOf(function () { return self.master / 2.2 + 1; });
    self.slave3 = makeValueOf(function () { return Math.floor(self.slave2); });

    return self;
}

var myObj = makeObj(6, 2);
alert(myObj.slave1 + 5); // 13