在Javascript中创建具有自定义get/put操作的关联数组

在Javascript中创建具有自定义get/put操作的关联数组,javascript,hashmap,associative-array,object-literal,Javascript,Hashmap,Associative Array,Object Literal,我需要创建一个Javascript对象,该对象将作为一个关联数组,但在获取和设置属性之前会调用一些函数 例如,任务可能是这样的:我们应该创建一个对象,其中包含一个键的平方值,如下所示: obj.two should be equal to 4, obj.four should be equal to 16, obj['twenty one'] should be equal to 441. 这是一个例子。实际上,我也需要使设置操作被覆盖。获取和设置操作将进入数据库,它们不一定将字符串作为键

我需要创建一个Javascript对象,该对象将作为一个关联数组,但在获取和设置属性之前会调用一些函数

例如,任务可能是这样的:我们应该创建一个对象,其中包含一个键的平方值,如下所示:

obj.two should be equal to 4, 
obj.four should be equal to 16, 
obj['twenty one'] should be equal to 441.
这是一个例子。实际上,我也需要使设置操作被覆盖。获取和设置操作将进入数据库,它们不一定将字符串作为键,而是将任何类型的对象作为键,从中创建DB查询

我将如何做到这一点a)使用尽可能少的第三方库和b)使其在尽可能多的平台上工作

我是JS新手,我发现JS没有关联数组,依赖于动态定义具有任意属性的对象的能力。我在谷歌上搜索了一下,想使用甚至覆盖lookupgetter(和setter),在这里动态定义一个新的getter/setter,但我不知道解释器是否会在每次遇到新键时都使用这个方法。不管怎样,看起来除了字符串或者数字之外,我什么都不能用

在Java中,我将只实现Java.util.Map

请帮助我,我将如何在Javascript中执行相同的操作

编辑

我想如果我能够覆盖这里提到的
[[get]]
[[Put]]]
方法,我会得到我想要的

还有这个特别的答案:

编辑

根据和没有很好的方式来实现确切的OP想要什么。getter和setter是没有用的,因为您必须事先知道您要查找的内容的名称

因此,我的建议是:

var database = {}
database.cache = {}
database.get = function(key) {
    // INSERT CUSTOM LOGIC to recognize "forty-two"
    if (!(key in database.data))
        database.cache[key] = fetch_data_from_database();
    return database.cache[key];
}
database.put = function(key, value) {
    database.cache[key] = value;
    send_data_to_database(key, value);
}

还有这个特别的答案:

编辑

根据和没有很好的方式来实现确切的OP想要什么。getter和setter是没有用的,因为您必须事先知道您要查找的内容的名称

因此,我的建议是:

var database = {}
database.cache = {}
database.get = function(key) {
    // INSERT CUSTOM LOGIC to recognize "forty-two"
    if (!(key in database.data))
        database.cache[key] = fetch_data_from_database();
    return database.cache[key];
}
database.put = function(key, value) {
    database.cache[key] = value;
    send_data_to_database(key, value);
}

举个例子,这不是你想要的吗:

var myObj = {};

myObj["two"] = 4;
myObj["four"] = 16;
myObj["twenty one"] = 441;

alert(myObj["four"]); // says 16
或者你是想说物体应该神奇地为你计算正方形

JavaScript对象键是字符串。如果尝试使用数字作为键,JavaScript基本上会首先将其转换为字符串

话虽如此,如果在对象上定义有意义的
toString
方法,则可以将对象用作键。但当然,有意义的事情是在个案的基础上发生的,只有你知道需要为你的个案做些什么


您还可以定义维护其自身内部数据结构的对象,您可以通过对象方法访问这些数据结构。我认为解释这一点超出了本文的范围。谷歌“javascript模块模式”中的一些指针,让您开始使用。

对于您的示例,这不符合您的要求吗:

var myObj = {};

myObj["two"] = 4;
myObj["four"] = 16;
myObj["twenty one"] = 441;

alert(myObj["four"]); // says 16
或者你是想说物体应该神奇地为你计算正方形

JavaScript对象键是字符串。如果尝试使用数字作为键,JavaScript基本上会首先将其转换为字符串

话虽如此,如果在对象上定义有意义的
toString
方法,则可以将对象用作键。但当然,有意义的事情是在个案的基础上发生的,只有你知道需要为你的个案做些什么


您还可以定义维护其自身内部数据结构的对象,您可以通过对象方法访问这些数据结构。我认为解释这一点超出了本文的范围。谷歌“javascript模块模式”为您提供一些指导。我认为实现这一点最正确的方法是使用Harmony:Proxies。它并不是在所有平台上都能工作,但它可以以最无缝的方式实现这一点;未来,它可能会在更多的平台上得到支持

此页面包含一个示例,我使用该示例作为模板来执行我想要的操作:


我认为实现这一点最正确的方法是使用Harmony:Proxies。它并不是在所有平台上都能工作,但它可以以最无缝的方式实现这一点;未来,它可能会在更多的平台上得到支持

此页面包含一个示例,我使用该示例作为模板来执行我想要的操作:


比如说,我如何将日期或更复杂的类型作为键?@Fyodor:您可以假设它们作为参数传递给getter和setter。语义完全取决于您。您甚至不需要在对象中存储任何内容。如果您决定在对象中存储内容,则键将自动转换为字符串;但你可以优雅地解决这个问题;有很多方法可以做到这一点,包括制作键=
[typeof(x),x]
(转换为字符串)的不太优雅的解决方案。@Fyodor:更详细地说,这将适用于任何对象,并且不限制您使用字符串,只要你没有在对象中存储任何东西。@ninjagecko-你在web上使用JS getter和setter吗?我以为IE不支持标准语法(可能在IE9中除外)。@ninjagecko,我搞不懂。我应该为每一个键定义无数的getter吗?我还不知道如何避免这种情况,比如说,我如何将日期或更复杂的类型作为键?@Fyodor:你可以假设它们作为参数传递给getter和setter。语义完全取决于您。您甚至不需要在对象中存储任何内容。如果您决定在对象中存储内容,则键将自动转换为字符串;但你可以优雅地解决这个问题;有很多方法可以做到这一点,包括制作键=
[typeof(x),x]
(转换为字符串)这一不太优雅的解决方案。@Fyodor:更详细地说,这是可行的