JQuery \ Javascript - 将函数作为变量传递

时间:2010-04-26 20:51:25

标签: javascript jquery

我只是好奇我是否可以将函数作为变量传递。例如: 我有一个功能

$('#validate').makeFloat({x:671,y:70,limitY:700});

我想做这样的事情:

$('#validate').makeFloat({x:function(){ return $("#tabs").offset().left+$("#tabs").width();},y:70,limitY:700});

这不起作用,但理想情况下,每次访问变量时,它都会计算新值。因此,如果调整窗口大小,它将自动调整,而不是传递给静态的变量。我意识到我可以直接在function \ widget中实现它,但我想知道是否有某种方法可以做上面这样的事情。

这个概念与插件无关。我说的是将“强制转换”的函数作为变量。

10 个答案:

答案 0 :(得分:2)

是的,您可以传递一个对象,该对象在读取其属性时会调用某些函数(这称为getter),但它不是跨浏览器兼容的。例如,这将(可能)在IE9中起作用:

var o = {y:70, limitY:700};
Object.defineProperty(o, 'x', {get: function() {return 671;}});
$('#validate').makeFloat(o);

其他浏览器还有其他语法,例如Firefox的__defineGetter__,有些浏览器根本没有此功能。因此,除非您可以完全控制代码运行的环境,否则它几乎没用。

答案 1 :(得分:1)

除非调用xobj.x(),而不只是obj.x),否则无效。

要使其正常工作,makeFloat()代码必须检查x的类型,如果它是函数,则调用它。

答案 2 :(得分:1)

我看到你正在尝试做什么,但它不起作用。为什么? makeFloat期望该值为非函数类型。它可能直接使用该值。要实际执行该功能,makeFloat需要执行x()甚至x.call(...)x.apply(...),而这肯定不会发生。

要回答你的另一个问题,即你能否将函数作为变量传递,答案是肯定的。实际上,这是在Javascript中处理回调和闭包的方式。例如,在jQuery中绑定事件处理程序时,您将函数作为参数传递:

jQuery("#myInputId").click(function() {
 ...
 ...
});

传入参数的另一种方式是作为对象属性,例如在jQuery.ajax:

jQuery.ajax({
   ...
   success: function(data) {
   },
   ...
});

在这两种情况下,clickajax都理解并期望参数是函数而不仅仅是常规变量。例如,假设您有一个维护整数列表的对象,并且您有一个名为addElement(int)的方法(预期int参数),则不会传入String。它在Javascript中的工作方式相同,除了语言不是强类型的事实。这就是为什么除非函数显式检查类型并抛出异常,否则不会出现类型不匹配错误。这通常是这种语言的一种很好的做法;我尝试在我编写的Javascript代码中执行此操作。

答案 3 :(得分:1)

我用字符串变量完成了这个。你需要利用toString函数。

function RefString(fn) { this.toString = function() { return String(fn()); }; }

您可以像这样使用它:

$("#someDiv").somePlugin({optionValue: new RefString(MyFunc), ... });

function MyFunc() {
  return new Date().getYear().toString();
}

它的工作原理是将optionValue设置为新的OBJECT,不一定是函数。然后,任何读取此对象的内容都会要求一个值,默认情况下该值是toString函数的结果。我们通过执行构造对象时指定的函数来覆盖默认行为。

我不确定它对每个插件的效果如何,但是当字符串或数字出现时它会起作用。

答案 4 :(得分:0)

你的意思是“不起作用”?

它看起来应该编译并运行。但是,它会执行函数并将值设置为与使用常量或调用非内联函数时的值无关。

您需要做的是将此行代码放在窗口重新调整大小时触发的事件中。

答案 5 :(得分:0)

看起来makeFloat来自jQuery插件 - 你确定插件知道'x'可以是一个函数并且会正确执行它吗?从jQuery站点看,它看起来只能将数字值或“当前”理解为字符串,而不是函数。

答案 6 :(得分:0)

您可以将函数作为变量传递,是 - 但实际上并不是您所要求的。

你的问题是“我可以将DOM属性设置为表达式的结果吗?”答案是“不”。 (注意 - 不要超出浏览器特定的行为,例如IE的CSS表达式 - 无论如何都已在IE8中弃用)

您需要将事件处理程序绑定到window.onresize并使用函数自行更新大小。

答案 7 :(得分:0)

为了从变量执行函数,必须调用它,如下所示:

$.option.callback.call();

option是包含变量的地方,callback是函数,call执行函数。

这并不像你没有选择。您可以对其进行设置,以便从该行本身执行该函数的返回值。或者您可以使用您描述的替代方式进行设置。

答案 8 :(得分:0)

请注意,x在访问(读取)时不会“计算新值”,而是在调用函数时,即x()。正如Chad所提到的,这是在调整窗口大小时自动执行函数的方法:

$(window).resize(function() {
    // do something
});

[更新]在重新阅读你的问题之后,我认为你可能会认为过于复杂 - 这不是你想要的吗?

$('#validate').makeFloat({
    x: $("#tabs").offset().left + $("#tabs").width(),
    y: 70,
    limitY: 700
});

答案 9 :(得分:0)

您需要调用该函数,以便它返回您正在寻找的实际值。所以你实际上并没有传入一个函数,你正在调用它并且它会立即返回一个值。例如:

$('#validate').makeFloat({
  x:function(){ 
    return $("#tabs").offset().left+$("#tabs").width();
  }(),
  y:70,
  limitY:700
});

注意函数调用后的extra()。这会立即调用函数,从而返回您正在寻找的值。