Javascript 使用\u堆栈的顶部\u(n).value访问类似堆栈的数组

Javascript 使用\u堆栈的顶部\u(n).value访问类似堆栈的数组,javascript,pass-by-reference,Javascript,Pass By Reference,TOS表示栈顶。预期用途的示例 read: var xx = tos(3).value; write: tos(4).value = 12345678; 给定一个数组 var mystack = [11, 22, 33, 44, 55]; // 55 is tos(0), 22 is tos(3) 阅读mystack很简单,tos(0)。value返回55,tos(1)。value返回44,如下所示 功能很好 function tos(n){ arguments.callee.v

TOS表示栈顶。预期用途的示例

 read: var xx = tos(3).value;
write: tos(4).value = 12345678;
给定一个数组

var mystack = [11, 22, 33, 44, 55];  // 55 is tos(0), 22 is tos(3)
阅读
mystack
很简单,
tos(0)。value
返回55,
tos(1)。value
返回44,如下所示 功能很好

function tos(n){
    arguments.callee.value = mystack[mystack.length - 1 - n];
    return arguments.callee;
}
但是我想通过

tos(2).value = 3333;  // How to make tos() work this way?
mystack
应该变成
[11,22,3333,44,55]如何为此重新写入
tos()

为什么要问这个问题

Microsoft office Excel automation允许objExcel.workbooks(1).worksheets(1).cells(1,1).value位于=,例如, 工作手册(1).工作表(1).单元格(1,1).值=11223344; echo(objExcel.workbooks(1).工作表(1).单元格(1,1).值);//打印11223344

我试图以这种方式访问阵列,但发现这对我来说很困难


预期的函数tos()是一个封装,可以避免暴露mystack本身。

假设您控制
mystack
变量,只需以不同的方式构建它,生活就会变得更轻松

利用JavaScript.Array的
shift
unshift
操作符。从堆栈为空开始: mystack=[]

添加时,只需移动值:

mystack.shift(11);
mystack.shift(22);
mystack.shift(33);
mystack.shift(44);
mystack.shift(55);
然后它将是一个索引为0的堆栈,
mystack[2]
将为您提供33,您只需执行
mystack[2]=3333
即可设置值


要“弹出”堆栈,请使用
unshift
。它将删除0元素。

如果您真的想这样做,坦率地说,我不认为这有什么意义,那么您可以:

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;
array.tos (2).value=999;
my_dom_array = new dom_array ([1,2,3]);

如果那能让你的船浮起来

根据您对这些事情的宗教信仰,您还可以将其添加到
数组中。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; }
    };
};
现在你可以做了

as_stack (array).tos (2).value=999;
array.tos (2).value=999;
my_dom_array = new dom_array ([1,2,3]);
另一种方法

如果您专注于使用
.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]);
    }
}
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;
};
接下来,我们将添加一个方法来返回特定元素:

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);
您可能需要添加一个成员函数以获取实际数组:

function dom_array (array) {
    this.frag = document.createDocumentFragment ();
    for (var i=0; i<array.length; i++) {
        this.frag.appendChild (document.createTextNode (array[i]);
    }
}
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;
};
dom_array.prototype.to_array=函数(){
var数组=[];

对于(var i=0;i,正如前面的一位评论者所指出的,您上面的代码非常奇怪。为了使您的代码看起来更好,如果
mystack
确实用作
Stack
Stack
数据类型,请使用以下命令:

mystack.push(11);
mystack.push(22);
mystack.push(33);
mystack.push(44);
mystack.push(55);
当然,您将在堆栈中拥有
[11、22、33、44、55]
。要查看堆栈顶部,您可能需要如下函数:

function peek(stack) {
  return stack[stack.length - 1];
}
或者您可以在
数组中定义它。prototype
为:

Array.prototype.peek = function () {
  return this[this.length - 1];
};

然后,您可以使用
mystack.peek()
访问堆栈顶部。现在您已经掌握了
堆栈的正确语义。虽然您不应该直接访问堆栈内部的元素,但仍然可以选择使用
mystack[2]修改它们=2222
如果真的有必要的话。

这是一个奇怪的代码,因为你提到了getter和setter,所以我投了更高的票,但是你的代码仍然需要一些调整,非常感谢。这是一个好方法。Microsoft office Excel automation允许objExcel.workbook(1)、worksheets(1)、cells(1,1).value位于=,我发现我不知道怎么做。tos()返回一个对象很有启发性.value出现在=的左边应该是一个feeference。为什么Excel可以这样做?Excel是Excel,JavaScript是JavaScript。语言设计师可以做任何他们想做的事情。非常感谢。Windows 8上的JScript不支持Object.defineProperty我需要找到一种替代方法。再次感谢。tos()是关于封装的。我不想被“mystack”这个名字束缚住。无论如何谢谢你。tos()是关于封装的。我不想被“mystack”这个名字束缚住。无论如何谢谢你。