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

发布于 2024-09-24 04:20:34 字数 402 浏览 7 评论 0原文

我正在尝试创建一个具有一系列“从属”属性的全局对象,这些属性是从同一对象中的一个“主”属性的值派生的 - 类似于:

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

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

I'm trying to create a global object with a series of 'slave' properties that are derived from the value of one 'master' property in the same object - something like:

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

I realize this is horribly wrong as is, but the concept is there. What I'd like to do is have all these 'slave' properties updated as myObj.master is updated. What's the cleanest way to do this? Does each slave value need to be explicitly set by some event handler that fires when myObj.master is changed...?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一场春暖 2024-10-01 04:20:34

如果您的目标不是 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() 函数访问从值。

If you are not targeting Internet Explorer users, try using getters and setters.

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

In action:

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

produces the output:

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

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

This code will never work in any version of Internet Explorer, past, present or future. However, it the slave values can still be accessed using the getSlaveX() functions.

歌入人心 2024-10-01 04:20:34

您可能最好使用函数。

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

You would probably be best off using functions.

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();
恏ㄋ傷疤忘ㄋ疼 2024-10-01 04:20:34

大卫的答案是一个选择,但如果您想缓存结果而不是每次都重新计算它们,请以相反的方式进行:

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

myObj.setMaster(17);

David's answer is one option, but if you want to cache the results instead of recalculating them every time, do it the other way round:

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

myObj.setMaster(17);
时光礼记 2024-10-01 04:20:34

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

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

Another option can be to use a constructor function to build your object, e.g:

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

In the above example I use a master argument and a reference to the x global property, if you don't have x available in that scope, you could provide also an argument for it.

You can also build your object in several steps:

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

myObj.slave1 = myObj.master + x;
myObj.slave2 = (myObj.master / 2.2) + 1;
myObj.slave3 = Math.floor(myObj.slave2);
沉鱼一梦 2024-10-01 04:20:34

您不想公开从站并允许设置它们,因为这会删除它们与主站的链接。所以它们应该是私有的。

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

You don't want to expose the slaves and allow them to be set since that would erase their link to master. So they should be private.

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
乄_柒ぐ汐 2024-10-01 04:20:34

您可以使用 valueOftoString 来模拟 getter,但它有点笨拙。

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

You could simulate getters using valueOf and toString, but it's a little unwieldy.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文