zoukankan      html  css  js  c++  java
  • (转)javascript中为何在匿名function函数后面还外加一个括号

    详细研究过Javascript代码库(如Jquery、YUI)的人,一定会看到过很多如下形式的函数:  (function(){...}())或 (function(){})()

    它可以解释成为“匿名函数自调用”,也就是说,定义一个匿名函数,然后马上调用它(因为它是匿名的,如果不立即调用就获取不到该函数的引用了)。通常它被应用在一些大型的JS框架中(如上面所说的),因为这个匿名函数的函数体相当于提供一个匿名的名字空间,这样就不会再与用户自定义的JS函数、变量、对象发生冲突了。尽管JS没有显示地提供命名空间的定义和使用机制,但这种匿名方式却不失为是一种很好的解决命名空间问题的方法。

    所以说,(function(){代码})()就等于执行了一个函数,只不过它是匿名的而已。如果在这个匿名函数内部想再次调用这个函数,就需要调用constructor属性了(这是Object中定义的,JS的继承机制如同Java一样保证了了所有对象都继承Object类)。

    具体举个例子:

            function test(){
                return (function(p1,p2){
                    return p1+p2;
                })(1,2);
            }
            (function(){
                alert(test());
            })();//3

    深入研究一下这种匿名函数:

            function Foo() {
                var a = 123;
                this.a = 456;
                (function () {
                    alert(a); // 123
                    alert(this.a); // undefined 
                })();
            };
            var f=new Foo();
    
    1         function Foo() {
    2             var a = 123;
    3             this.a = 456;
    4             (function (_this) {
    5                 alert(a); // 123
    6                 alert(_this.a); // 456 
    7             })(this);
    8         };
    9         var f = new Foo();

    以上两个对比,说明:

    (1)匿名函数可以直接访问到外层署名函数(Foo)中的变量(使用关键字var定义的),但不能访问外层署名函数的属性(使用关键字this定义的);

    (2)匿名函数中的this指向的是匿名函数对象的地址,它与外层署名函数(Foo)对象的this指向的地址不同;

    (3)匿名函数若要访问外层署名函数(Foo)中的属性,可以通过参数传递的方式实现。

    1         function Foo() {
    2             var a = 123;
    3             this.a = 456;
    4             (function (b) {
    5                 alert(a); // 123
    6                 alert(b); // 456 
    7             })(this.a);
    8         };
    9         var f = new Foo();
    1         (function () {
    2             var a = 123;
    3             this.a = 456;
    4             (function () {
    5                 alert(a); // 123
    6                 alert(this.a); // 456 
    7             })();
    8         })();

    以上两个对比,说明:

    (1) 匿名函数既可以直接访问外层匿名函数中的变量,又直接可以访问外层匿名函数中的属性,而匿名函数却不可以直接访问外层已命名函数中的属性;

    (2)以上两种方式可以实现相同的功能。

     1         (function () {
     2             var a = 123;
     3             this.a = 456;
     4             (function () {
     5                 alert(a); // 123 
     6                 alert(this.a); // 456 
     7                 this.b = 789;
     8             })();
     9             (function () {
    10                 alert(this.b); // 789 
    11             })();
    12         })();
    13         (function () {
    14             alert(this.a); // 456
    15             alert(this.b); // 789 
    16         })();
     1         function Foo() {
     2             var a = 123;
     3             this.a = 456;
     4             (function () {
     5                 alert(a); // 123 
     6                 alert(this.a); // undefined 
     7                 this.b = 789;
     8             })();
     9             (function () {
    10                 alert(this.b); // 789 
    11             })();
    12         };
    13         var f = new Foo();
    14         (function () {
    15             alert(this.a); // undefined
    16             alert(this.b); // 789 
    17         })();

    以上两个对比,说明:

    (1)匿名函数(即用两个小括号括起来的部分)位于一个执行上下文,不论这些代码放在哪个位置上。

     1         function Foo() {
     2             (function () {
     3                 this.b = 789;
     4             })();
     5             (function () {
     6                 alert(this.b); // 789
     7                 alert(b); // 789
     8                 var a = 0;
     9                 alert(a); // 0
    10             })();
    11         }
    12         var f = new Foo();
    13         (function () {
    14             alert(this.b); // 789
    15             alert(b); // 789
    16         })();
     1         function Foo() {
     2             (function () {
     3                 this.b = 789;
     4             })();
     5             (function () {
     6                 alert(this.b); // 789
     7                 alert(b); // undefined
     8                 var b = 0;
     9                 alert(b); // 0
    10             })();
    11         }
    12         var f = new Foo();
    13         (function () {
    14             alert(this.b); // 789
    15             alert(b); // 789
    16         })();

    以上两个对比,说明:

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

    转载地址

  • 相关阅读:
    20145240《网络对抗》逆向及Bof基础实践
    20145239杜文超《网络对抗》- Web安全基础实践
    20145239杜文超《网络对抗》- Web基础
    20145239杜文超《网络对抗》- 网络欺诈技术防范
    20145239杜文超《网络对抗》- 信息搜集与漏洞扫描
    20145239杜文超《网络攻防》- MSF基础应用
    20145239杜文超《网络对抗》- 恶意代码分析
    20145239杜文超《网络对抗》- shellcode注入&Return-to-libc攻击深入
    20145239杜文超《网络对抗》- 免杀原理与实践
    20145239《网络对抗》- 后门原理与实践
  • 原文地址:https://www.cnblogs.com/Syinho/p/11397865.html
Copyright © 2011-2022 走看看