使用 top_of_stack(n).value 访问像堆栈一样的数组
Access an array like a stack using top_of_stack(n).value
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;
}
但是我想将数据写入mystack
tos(2).value = 3333; // How to make tos() work this way?
mystack
应该变得[11, 22, 3333, 44, 55];
如何为此重写tos()
?
为什么要问这个问题?
Microsoft办公 Excel 自动化允许 objExcel.workbooks(1(.worksheets(1(.cells(1,1(.value 位于 = 的两侧,例如,objExcel.workbooks(1(.worksheets(1(.cells(1,1(.value = 11223344;WScript.echo(objExcel.workbooks(1(.worksheets(1(.cells(1,1(.value(;打印11223344
我尝试以这种方式访问数组,但发现这对我来说很困难。
预期的函数 tos(( 是一个避免暴露 mystack 本身的封装。
如果你真的想这样做,坦率地说我不明白这一点,那么你可以这样做:
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
或 pop
或其他任何方法。
你有它 - 一个tos
函数,它允许您获取和设置数组中的值,尽管使用 nodeValue
而不是 value
。然而,它使你无法想象为什么你想要这样做,而不是像世界上所有其他JS程序员一样说array[2]=999;
。
请注意,这在非 DOM 环境中不起作用,例如 node.js。
假设你控制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 元素。
正如之前的评论者指出的那样,您上面的代码非常奇怪。若要使代码看起来更好,如果确实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];
}
或者,您可以在Array.prototype
中将其定义为:
Array.prototype.peek = function () {
return this[this.length - 1];
};
然后,您可以使用mystack.peek()
访问堆栈顶部。现在您拥有了stack
的正确语义。虽然您不应该真正直接访问堆栈中的元素,但如果确实有必要,您仍然可以选择使用 mystack[2] = 2222
修改它们。
- Rails File_field最大堆栈大小
- d3中堆栈函数和嵌套函数之间的差异
- 是什么让一个“;Uncaught RangeError:超过了最大调用堆栈大小“;错误(Chrome,在其他浏览器中显示
- 使用向下箭头键(与tab键一样)聚焦下一个输入
- 为什么我的JavaScript堆栈排序函数不起作用
- 超过了async.detect最大调用堆栈大小
- 如何远程检查JavaScript应用程序的函数调用堆栈
- 在SVG地图上添加水的渐变,就像在谷歌地图(PHP/JS)中一样
- 如何像模糊图像一样模糊iframe
- 超过了最大调用堆栈大小,循环无限
- FullCalendar:事件发生时阻止重叠.标题是一样的
- 如何检测滚动事件是否像在触摸设备上一样只触发一次
- Fresh Spark Install+Homestead上的Vue异步堆栈跟踪错误
- DIV怎么能像Javascript中的另一个元素一样工作呢
- 我正在创建一个聊天,但每次我发送消息时,它都不会让我再发送另一条消息,就像表格一样;不起作用
- 超过了最大调用堆栈大小.递归标签
- 使用MEAN堆栈-查询MongoDB并将值作为变量传递
- 日志:未捕获的范围错误:超过了最大调用堆栈大小
- 使用 top_of_stack(n).value 访问像堆栈一样的数组
- 异步执行某个东西,就像将它推到调用堆栈的后面一样