我想包装一些动态创建的javascript函数,类似于Daniel在此处接受的答案: How do I store javascript functions in a queue for them to be executed eventually
// Function wrapping code.
// fn - reference to function.
// context - what you want "this" to be.
// params - array of parameters to pass to function.
var wrapFunction = function(fn, context, params) {
return function() {
fn.apply(context, params);
};
}
不同之处在于我希望参数值在执行时是动态的 - 是否可以在参数中传递对变量的引用,这可以在它被包装后更新?
这是我想做的事情:
// I have a function to be wrapped
var sayStuff = function(a,b) {
console.log(a);
console.log(b);
}
// Variables I'd like to pass
var randomNumberA = 0;
var randomNumberB = 0;
// Wrap the function
var fun = wrapFunction(sayStuff, this, [*reference randomNumberA*,*reference randomNumberB*]);
// variables get changed
randomNumberA = Math.random()*100;
randomNumberB = Math.random()*100;
// Execute the function using current values of randomNumberA & randomNumberB
fun();
如果可能的话我想在不更改sayStuff的情况下这样做,我有很多现有的功能,我希望包装,也可以在包装外使用,所以理想情况下我不想更换一个对象的参数。 希望有道理,谢谢!
答案 0 :(得分:1)
如果在context参数中定义了动态参数,则解决方案可以基于传递变量的名称,然后在执行时计算其当前值:
var wrapFunction = function(fn, context) {
var xArg = arguments;
return function() {
var argsArray = [];
for (var i = 2; i < xArg.length; i++) {
argsArray.push(context[xArg[i]]);
}
fn.apply(context, argsArray);
};
}
var sayStuff = function() {
for (var i = 0; i < arguments.length; i++) {
console.log('sayStuff func: ' + arguments[i]);
}
}
var randomNumber1 = 0;
var randomNumber2 = 0;
var fun = wrapFunction(sayStuff, this, 'randomNumber1', 'randomNumber2');
randomNumber1 = Math.random()*100;
randomNumber2 = Math.random()*100;
console.log('randomNumber1: ' + randomNumber1);
console.log('randomNumber2: ' + randomNumber2);
fun();
&#13;
答案 1 :(得分:1)
如果函数和变量将在同一范围内创建,您可以使用它:
var randomNumber = 0;
var fun = function(){ alert(randomNumber); }
randomNumber = 10;
// Now this will alert 10, because when fun is executed
// JS looks in his scope to find what randomNumber is.
fun();
这是因为javascript中的函数用作Closures,它们随身携带它们的环境。请参阅:https://en.wikipedia.org/wiki/Closure_(computer_programming)
因此,如果将randomNumber
更改为绑定该函数的范围,则需要使用一个对象,这是因为在javascript中我们没有&#34;指针&#34;或引用通过。一种方法是使用对象。
function giveMeAFunction(){
var params = { randomNumber: 0 }
var fun = function(){ alert(scope.randomNumber); }
return {fun: fun, scope: scope};
}
var paramsAndFun = giveMeAFunction()
// Now you can change the variables in the scope and call the function
paramsAndFun.params.randomNumber = 10;
paramsAndFun.fun(); // Will alert 10
// Now if you replace the entire params object it will not work
// This is because you will replacing it with a new object while
// The one that is referenced in the scope where fun was created is
// the old one.
paramsAndFun.params = { randomNumber: 15 };
paramsAndFun.fun(); // will still alert 10
现在让我们解决部分问题。
已经有Function.prototype.bind功能可以帮助您。
例如:
var sayStuff = function(opts) {
alert(otions.randomNumber);
}
var options = { randomNumber: 0 };
var fun = sayStuff.bind(this, options);
options.randomNumber = 10;
fun(); // Will print 10
这里有很多事情要发生。对不起,如果我把一切都搞糊涂了。