2012-04-08 33 views
2

相当于我发现这个话题,我已经实现(见接受的答案):
javascript equivalent of PHP's call_user_func()JavaScript的PHP的call_user_func

不过,我有多个参数有问题。我意识到我正在做的是将我的参数转换为字符串并将其视为1参数,但我不知道如何解决此问题,因为我动态创建参数。

含义,我在我的代码定义如下:

var a = new Array(); 
a[0] = new Array(); 
a[0][0] = 'alert'; 
a[0][1] = '\'Hello World\''; 
a[1] = new Array(); 
a[1][0] = 'setTimeout'; 
a[1][1] = 'alert("goodbye world")'; 
a[1][2] = '20'; 

后来,我称他们是这样的:

var j = 0; 
    var len = 0; 
    var fx = ''; 
    var params = ''; 
    for(i in a){ 
     params = ''; 
     len = a[i].length; 
     fx = a[i][0]; // getting the function name 
     a[i].splice(0, 1); // removing it from array 
     if(len > 1){ 
      params = a[i].join(", "); // trying to turn the parameters into the right format, but this is turning it into strings I think 
      params = params.replace(/\\'/g,'\''); // bc i was adding slashes with PHP 
     } 
     window[fx](params); 
    } 

我没有使用数组来做到这一点。我不明白JS OOP(还没有尝试过),但我很喜欢PHP OOP,所以我不知道是否有办法在那里做到这一点。

任何帮助传递多个参数将不胜感激。

谢谢。

+1

'window [fx] .apply(obj,params)' – Cheeso 2012-04-08 08:19:01

+2

你在这里拍摄自己的脚。对于初学者:你不应该有一个包含代码为* strings *的数组,这是错误的。不要让我开始用正则表达式来解释这些字符串。你想做什么?进一步:**从不**在数组中使用'for .. in'循环,并且根本不应该使用'new Array()'。 – Tomalak 2012-04-08 08:42:42

回答

11

首先要做的:报废整个代码,从头开始。你的方法不会让你在任何你想要的地方。 (不幸的是,我不能告诉你你想成为什么样的人,因为我无法理解你的例子。)

有三种方法可以在JavaScript中调用函数。

function foo() { console.log(arguments); } 

// 1. directly 
foo(1, 2, 3); 

// 2. trough Function.call() 
foo.call(this, 1, 2, 3); 

// 3. trough Function.apply() 
var args = [1, 2, 3]; 
foo.apply(this, args); 

callapply是相似的。他们让你决定哪个对象this关键字将指向函数内部(这是重要的一点!)。

apply接受参数数组,call接受单独的参数。

最接近call()的是PHP的call_user_func()。与apply()最接近的是PHP的call_user_func_array()

JavaScript对象与PHP数组共享:它们是键/值对。

var obj = { 
    foo: function() { console.log(arguments); } 
}; 

这意味着你可以用点号访问对象属性:

obj.foo(1, 2, 3); 

还是通过方括号(注意对象键是字符串):

var key = "foo"; 
obj[key](1, 2, 3); 
obj[key].call(obj, 1, 2, 3); 
obj[key].apply(obj, [1, 2, 3]); 

括号符号给你自由选择动态的对象属性。如果这个属性恰好是一个函数,apply()给你动态选择函数参数的自由。

未被声明为特定对象属性的每个函数或变量都将成为全局对象的属性。在浏览器中,全局对象是window。 (所以在我上面的第一个代码块foo真的是window.foo。)

请注意,this不像PHP中的工作。它将指向函数已在上调用的对象,而不是函数“属于”的对象。 (这个概念“属于”根本不存在在JavaScript;东西都可以模仿方式,但它仅仅是一个惯例)

采用直接调用(obj.foo(1, 2, 3)),this将指向obj。用callapply,this将指向你想要的任何对象。这听起来比起初听起来有用得多。大多数情况下,当你想动态地调用函数时,你最终会使用apply

1

退房Function.apply:

function test(a, b) { console.log([a, b]) } 

test.apply(null, [1, 2]); // => [ 1, 2 ]