Javascript之匿名函数

详细研究过Javascript代码库(如Jquery、YUI)的人,一定会看到过很多如下形式的函数: (function(){...}()) 或 (function(){})()
  对于很多初学者来说,遇到它们经常会产生一系列问号:这是编程吗,用它做什么,怎么我没在其他语言里见过呢?
  接下来我就详细地解释一下:
  它可以解释成为“匿名函数自调用”,也就是说,定义一个匿名函数,然后马上调用它(因为它是匿名的,如果不立即调用就获取不到该函数的引用了)。通常它被应用在一些大型的JS框架中(如上面所说的),因为这个匿名函数的函数体相当于提供一个匿名的名字空间,这样就不会再与用户自定义的JS函数、变量、对象发生冲突了。尽管JS没有显示地提供命名空间的定义和使用机制,但这种匿名方式却不失为是一种很好的解决命名空间问题的方法。
  所以说,(function(){代码})()就等于执行了一个函数,只不过它是匿名的而已。如果在这个匿名函数内部想再次调用这个函数,就需要调用constructor属性了(这是Object中定义的,JS的继承机制如同Java一样保证了了所有对象都继承Object类)。
  明白了它是什么了,下面我们就要学习该怎样使用它了,以下这些问题是我们会经常遇到的,不如提前做好理论只是准备以备后期能顺利地实现开发。请看下面问题:
  1、下列哪些正确?(B、C)
  A.function(){
  alert("Here!");
  }();
  B.(function(){
  alert("Here!");
  })();
  C.(function(){
  alert("Here!");
  }());
  2、下列哪个结果是正确的?(A、B、C、D)
  A.(function(a1,a2){
  alert("Here!"+(a1+a2));
  })(1,2);
  B.(function(a1,a2){
  alert("Here!" +(a1+a2));
  }(1,2));
  C.void function(a1,a2){
  alert("Here!" +(a1+a2));
  }(1,2);
  D.var f = function(a1,a2){
  alert("Here!" +(a1+a2));
  }(1,2);
  注:A 、B、C与D四种格式都正确,前两者属于同种情况的不同写法,后两种是将函数对象的返回值赋给其他变量,C是忽略函数返回值,而D正相反!
  具体举个例子:
  function test(){
  return (function(p1,p2){
  return p1+p2;
  })(1,2);
  };
  (function(){
  alert(test());
  }());
  下面我们就深入研究一下这种匿名函数:
  1、
  ①
  function Foo() {
    var a = 123;
    this.a = 456;
    (function() {
      alert(a); // 123
  alert(this.a); // undefined
    })();
  };
  var f = new Foo();
  ②
  function Foo() {
    var a = 123;
    this.a = 456;
    (function(_this) {
      alert(a); // 123
  alert(_this.a); // 456
    })(this);
  };
  var f = new Foo();
  以上两个对比,说明:
  (1)匿名函数可以直接访问到外层署名函数(Foo)中的变量(使用关键字var定义的),但不能访问外层署名函数的属性(使用关键字this定义的);
  (2)匿名函数中的this指向的是匿名函数对象的地址,它与外层署名函数(Foo)对象的this指向的地址不同;
  (3)匿名函数若要访问外层署名函数(Foo)中的属性,可以通过参数传递的方式实现。
  2、
  ①
  function Foo() {
    var a = 123;
    this.a = 456;
    (function(b) {
      alert(a); // 123
  alert(b); // 456
    })(this.a);
  };
  var f = new Foo();
  ②
  (function() {
    var a = 123;
    this.a = 456;
    (function() {
      alert(a); // 123
  alert(this.a); // 456
    })();
  })();
  以上两个对比,说明:
  (1) 匿名函数既可以直接访问外层匿名函数中的变量,又直接可以访问外层匿名函数中的属性,而匿名函数却不可以直接访问外层已命名函数中的属性;
  (2)以上两种方式可以实现相同的功能。
  3、
  ①
  (function() {
    var a = 123;
  this.a = 456;
    (function() {
      alert(a); // 123
  alert(this.a); // 456
  this.b = 789;
    })();
    (function() {
  alert(this.b); // 789
    })();
  })();
  (function() {
  alert(this.a); // 456
  alert(this.b); // 789
  })();
  ②
  function Foo() {
    var a = 123;
  this.a = 456;
    (function() {
      alert(a); // 123
  alert(this.a); // undefined
  this.b = 789;
    })();
    (function() {
  alert(this.b); // 789
    })();
  };
  var f = new Foo();
  (function() {
    alert(this.a); // undefined
  alert(this.b); // 789
  })();
  以上两个对比,说明:
  (1)匿名函数(即用两个小括号括起来的部分)位于一个执行上下文,不论这些代码放在哪个位置上。
  4、
  ①
  function Foo() {
  (function() {
  this.b = 789;
  })();
  (function() {
  alert(this.b); // 789
  alert(b); // 789
  var a = 0;
  alert(a); // 0
  })();
  }
  var f = new Foo();
  (function() {
  alert(this.b); // 789
  alert(b); // 789
  })();
  ②
  function Foo() {
  (function() {
  this.b = 789;
  })();
  (function() {
  alert(this.b); // 789
  alert(b); //undefined
  var b = 0;
  alert(b); // 0
  })();
  }
  var f = new Foo();
  (function() {
  alert(this.b); // 789
  alert(b); // 789
  })();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值