zoukankan      html  css  js  c++  java
  • (function(){代码})()自执行函数

    javascript中为何在匿名function函数后面还外加一个括号

      详细研究过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

      })();

      以上两个对比,说明:

      (1)没有加 this取值时,如果当前 {} 中不存在同名的局部变量,则等同于加 this 处理;如果当前 {} 中存在同名的局部变量,则按常规处理。

      以上只是鄙人的粗浅见解,内容还不够完整,还会不断完善删改,如其中有什么错误之处还望读者谅解,真诚希望能留下您的宝贵建议,以图修改!这里欢迎每一位爱好JS的读者,真心希望能和你们交流心得!

  • 相关阅读:
    改变页面选择文字颜色和背景颜色----selection伪元素
    中文版Chrome浏览器不支持12px以下字体的解决方案
    css直接写出小三角
    解决ie6 闪动的问题
    去掉firefox点击按钮时的虚线边框
    去除input在谷歌下的focus效果
    文本输入框的两种div+css的写法
    常用排序算法
    wtforms
    Flask
  • 原文地址:https://www.cnblogs.com/h5monkey/p/6748746.html
Copyright © 2011-2022 走看看