作为我正在构建的Web应用程序的一部分,可以立即从服务器进入多个命令。
处理这些命令时,数据往往会更新,然后可能会发生相当繁重的页面HTML生成。
当多个类似命令进入时,程序将处理数据,然后每次重新生成部分页面。这可能会导致大量浪费的处理时间。
因此,我正在尝试创建一个callstack,所以当处理一个命令时,它会查看命令触发的函数是否在堆栈中,如果没有找到它会添加它。
我的问题是将callstack中的被调用函数保持在正确的范围内,同时还能够消除重复。
基本代码:
var tools = {
functions:{
function1: function(){
return this;
},
function2: function(){
}
},
unique: function(arr){
var returnArr=[],
x, i;
for (x=0; x<arr.length; x++){
for (i=(x+1); i<arr.length; i++){
if (arr[x]===arr[i]){
arr.splice(i, 1);
}
}
returnArr.push(arr[x]);
}
return returnArr;
}
}
示例1:
var callstack=[tools.functions.function1, tools.functions.function1];
callstack = tools.unique(callstack);
for (var x=0; x<callstack.length; x++){
console.log(callstack[x](), "should equal tools.functions");
}
这失败,因为“this”将返回[function()]
示例2:
var callstack=[
(function(){return tools.functions.function1()}),
(function(){return tools.functions.function1()})
];
callstack = tools.unique(callstack);
for (var x=0; x<callstack.length; x++){
console.log(callstack[x](), "should equal tools.functions");
}
这会失败,因为您无法确保这些函数是唯一的,因此它仍会运行该函数两次。
这可以通过使用两个数组(一个跟踪函数名称,一个保存封装函数)并保持同步来解决,但我不禁觉得必须有一个更清洁使用.call的方式,但我看不到它。
JSFiddle:http://jsfiddle.net/Kj6E8/
答案 0 :(得分:1)
在JavaScript中,this
是从外部调用者定义的,所以当你这样做时:
callstack[x]()
您将window
范围带入函数中。如果要引入tools.functions
对象,则需要执行以下操作:
callstack[x].call(tools.functions);
答案 1 :(得分:1)
一般来说,不可能以您需要的方式保留this
的值。只要将这些函数推入数组,这些函数曾经驻留的对象就会丢失。
如果您只是在单个对象上调用函数,则需要以某种方式将函数绑定到该对象。有很多方法可以做到这一点,例如,您可以传递对象以将这些函数绑定到您的独特函数中。
var tools = {
functions:{
function1: function(){
return this;
},
function2: function(){
}
},
unique: function(arr, o){
var returnArr=[],
x, i;
for (x=0; x<arr.length; x++){
for (i=(x+1); i<arr.length; i++){
if (arr[x]===arr[i]){
arr.splice(i, 1);
}
}
returnArr.push(this.bind(arr[x], o));
}
return returnArr;
},
bind: function(f, o) {
return function () {
return f.apply(o, arguments);
}
}
}
console.info("Example 1:");
var callstack=[tools.functions.function1, tools.functions.function1];
callstack = tools.unique(callstack, tools.functions);
console.log("Callstack:",callstack);
for (var x=0; x<callstack.length; x++){
console.log(callstack[x](), "should equal tools.functions");
}
如何以及何时推断this
的值实际上取决于您在范围内拥有该对象的时间。据推测,在callstack创建阶段,您更有可能在范围内拥有该对象,并且可能不一定在您希望调用callstack中的函数的位置。如果是这种情况,尽可能早地进行绑定(即在缩减到显示的唯一调用堆栈期间)似乎是一个明智的选择。