0 Comments

函数调用

发布于:2014-04-01  |   作者:广州网站建设  |   已聚集:人围观

函数调用

在JavaScript 中,函数和其他东西一样都是对象。然而,和其他对象不同的是,函数是可调用的。函数内上下文,如this 的取值,取决于调用它的位置和方法。

除了使用方括号调用函数之外,还有其他两种方法可以调用函数:apply() 和call()。两者的区别在于传入函数的参数的形式。

apply() 函数有两个参数:第1 个参数是上下文,第2 个参数是参数组成的数组。如果上下文是null,则使用全局对象代替。例如:


  1. function.apply(this, [1, 2, 3]) 

广州网站建设,广州网站设计,广州网站制作,网站建设,网站设计,广州网站建设公司,广州网站设计公司

call() 函数的行为和apply() 函数的并无不同,只是使用方法不一样。call() 的第1 个参数是上下文,后续是实际传入的参数序列。换句话说,这里使用多参数——而不是类似apply() 的数组——来将参数传入函数。

  1. function.call(this, 1, 2, 3); 

为什么要更换上下文?这的确是一个问题,因为其他编程语言不允许手动更换上下文也没什么不好。JavaScript 中允许更换上下文是为了共享状态,尤其是在事件回调中。(依个人所见,这是语言设计中的一个错误,因为这会对初学者造成一些困扰,并引入一些bug。但亡羊补牢为时已晚,你需要花精力来弄清楚它们是如何工作的。)

jQuery 在其API 的实现中就利用了apply() 和call() 来更改上下文,比如在事件处理程序中或者使用each() 来做迭代时。起初这很让人费解,一旦你理解了就会发现它非常有用:


  1. $('.clicky').click(function(){  
  2. // ‘this’指向当前节点  
  3. $(this).hide();  
  4. });  
  5. $('p').each(function(){  
  6. // ‘this’指向本次迭代  
  7. $(this).remove();  
  8. }); 

广州网站建设,广州网站设计,广州网站制作,网站建设,网站设计,广州网站建设公司,广州网站设计公司

为了访问原始上下文,可以将this 的值存入一个局部变量中,这是一种常见的模式,比如:

  1. var clicky = {  
  2. wasClicked: function(){  
  3. /* ... */  
  4. },  
  5. addListeners: function(){  
  6. var self = this;  
  7. $('.clicky').click(function(){  
  8. self.wasClicked()  
  9. });  
  10. }  
  11. };  
  12. clicky.addListeners(); 

 

然而,我们可以使用apply来将这段代码变得更干净一些,通过将回调包装在另外一个匿名函数中,来保持原始的上下文:

  1. var proxy = function(func, thisObject){  
  2. return(function(){  
  3. return func.apply(thisObject, arguments);  
  4. });  
  5. };  
  6. var clicky = {  
  7. wasClicked: function(){  
  8. /* ... */  
  9. },  
  10. addListeners: function(){  
  11. var self = this;  
  12. $('.clicky').click(proxy(this.wasClicked, this));  
  13. }  
  14. }; 

因此在上面的例子中,我们在点击事件的回调中指定了要使用的上下文;jQuery 中调用这个函数所用的上下文就可以忽略了。实际上,jQuery 也包含了实现这个功能的API,

你或许已经猜到了,就是jQuery.proxy() :


  1. $('.clicky').click($.proxy(function(){ /* ... */ }, this)); 

 

使用apply() 和call() 还有其他很有用的原因,比如“委托”。我们可以将一个调用委托给另一个调用,甚至可以修改传入的参数:

  1. var App {  
  2. log: function(){  
  3. if (typeof console == "undefined") return;  
  4. // 将参数转换为合适的数组  
  5. var args = jQuery.makeArray(arguments);  
  6. // 插入一个新的参数  
  7. args.unshift("(App)");  
  8. // 委托给console  
  9. console.log.apply(console, args);  
  10. }  
  11. }; 

 

在这个例子中首先构建了一个参数数组,然后将我们自己的参数添加进去,最后将这个调用委托给了console.log()。你可能对arguments 变量不熟悉,它是当前调用的作用域内解释器内置的用来保存参数的数组。但它并不是真正的数组,比如它是不可变的,因此我们需要通过jquery.makeArray() 将其转换为可用的数组。
标签:
飞机