如果你真的想这样做,坦率地说我不明白这一点,那么你可以这样做:
function tos (n) {
var i = mystack.length - n - 1;
return Object.defineProperty ({}, "value", {
get : function() { return mystack[i]; },
set : function(v) { mystack[i] = v; }
});
}
当然你需要 ECMAScript 5。没有其他方法可以实现tos(2).value=999
设置数组元素的语义,因为在 JS 中,.value
语法要求左边的对象是一个对象,而数组元素本身就是一个对象不是可以设置值的对象。所以上面本质上构造了一个对象,并在其上定义了一个getter和setter。
要使其独立于mystack
,请执行以下操作:
function as_stack (array) {
return {
tos : function (n) {
var i = array.length - n - 1;
return Object.defineProperty ({}, "value", {
get : function() { return array[i]; },
set : function(v) { array[i] = v; }
};
}
};
}
现在你可以做
as_stack (array).tos (2).value=999;
或者
var tos = as_stack (array).tos;
tos (2).value = 999;
如果那能让你的船浮起来。
根据您对此类事情的宗教信仰,您还可以将其添加到Array.prototype
:
Array.prototype.tos = function (n) {
var i = this.length - n - 1, array = this;
return Object.defineProperty ({}, "value", {
get : function() { return array[i]; },
set : function(v) { array[i] = v; }
};
};
现在你可以做
array.tos (2).value=999;
另一种方法
如果您专注于使用.value
语法来获取和设置值,而不使用Object.defineProperty
,那么我能想到的唯一其他选择是使用 DOM 作为数组的代理。我们将数组存储为文档片段中的文本节点列表。但是,您必须使用nodeValue
,而不是value
。
首先,从一个真实数组创建一个基于 DOM 的数组:
function dom_array (array) {
this.frag = document.createDocumentFragment ();
for (var i=0; i<array.length; i++) {
this.frag.appendChild (document.createTextNode (array[i]);
}
}
现在,你可以做
my_dom_array = new dom_array ([1,2,3]);
接下来,我们将添加一个返回特定元素的方法:
dom_array.prototype.tos = function (n) {
return this.frag.childNodes.item (this.frag.childNodes.length - n -1 );
}.
此函数实际上返回一个 DOM 文本节点,您现在可以使用它来执行以下操作:
my_dom_array.tos (2).nodeValue = "bar";
alert (my_dom_array.tos (2).nodeValue);
您可能需要添加一个成员函数来取回一个真正的数组:
dom_array.prototype.to_array = function () {
var array=[];
for (var i=0; i<this.frag.childNodes.length; i++) {
array.push (this.frag.childNodes[i].nodeValue);
}
return array;
};
现在您可能还想在这个准数组上实现所有其他数组方法,例如push
or或其他任何东西。pop
你有它 - 一个tos
允许你获取和设置数组中的值的函数,尽管使用nodeValue
而不是value
. 但是,它使您难以想象为什么要这样做,而不是array[2]=999;
像世界上其他所有 JS 程序员一样说。
请注意,这不适用于非 DOM 环境,例如 node.js。