JS里面匿名函數的調用 & 變量作用域的實驗


參考 http://www.educity.cn/wenda/54753.html

已實驗驗證結果正確。

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 Foo() {
    var a = 123;
    this.a = 456;
    (function() {
        console.log(a); // 123
        console.log(this.a); // undefined
    })();
};
var f = new Foo();

結果:
123
undefined

(1)匿名函數可以直接訪問到外層署名函數(Foo)中的變量(使用關鍵字var定義的),但不能訪問外層署名函數的屬性(使用關鍵字this定義的);

稍微改一下,把Foo前面的new去掉,直接調用Foo,如下:

function Foo() {
    var a = 123;
    this.a = 456;
    (function() {
        console.log(a); // 123
        console.log(this.a); // undefined
    })();
};
var f = Foo();

結果:
123
456

然后在最后分別加上console.log(f)看看f被賦予什么內容:

var f = new Foo();
console.log(f);

結果:
Foo { a: 456 }

var f = Foo();
console.log(f);

結果:
undefined

開始寫自己代碼的時候,發現了下面的情況。本來以為是node跟原生js的區別呢,看來不是。

/**
 * Created by baidu on 16/10/24.
 */
function test(){
    var a = 123;
    this.a = 456;
    return (function(p1,p2){
        console.log(a);
        console.log(this.a);
        return p1+p2;
    })(1,2);
};
(function(){
    console.log(test());
}());

用node跑:
123
456
3

內部要訪問數據,可以通過傳參數(方法一):

function Foo() {
    var a = 123;
    this.a = 456;
    (function(_this) {
        console.log(a); // 123
        console.log(_this.a); // 456
    })(this);
};
var f = new Foo();

結果:
123
456

另外,注意下面這種情況:

(function() {
    var a = 123;
    this.a = 456;
    (function() {
        console.log(a); // 123
        console.log(this.a); // 456
    })();
})();

結果:
123
4561) 匿名函數既可以直接訪問外層匿名函數中的變量,又直接可以訪問外層匿名函數中的屬性,而匿名函數卻不可以直接訪問外層已命名函數中的屬性;

訪問沒有定義過的this.xxx,也是很有意思的:

/**
 * Created by baidu on 16/10/24.
 */

function Foo() {
    var a = 123;
    this.a = 456;
    (function() {
        console.log(a); // 123
        console.log(this.a); // undefined
        this.b = 789;
    })();
    (function() {
        console.log(this.b); // 789
    })();
};
var f = new Foo();
(function() {
    console.log(this.a); // undefined
    console.log(this.b); // 789
})();
結果:

123
undefined
789
undefined
789

后面分析。

再來一個里外都是匿名函數的情況:

/**
 * Created by baidu on 16/10/24.
 */

(function() {
    var a = 123;
    this.a = 456;
    (function() {
        console.log(a); // 123
        console.log(this.a); // 456
        this.b = 789;
    })();
    (function() {
        console.log(this.b); // 789
    })();
})();
(function() {
    console.log(this.a); // 456
    console.log(this.b); // 789
})();

結果:
123
456
789
456
789

通過上面兩個例子的對比及分析,可以看出如下結論:

(1)匿名函數(即用兩個小括號括起來的部分)位於一個執行上下文,不論這些代碼放在哪個位置上。

再比較下面兩種情況:

情況1:

function Foo() {
    (function() {
        this.b = 789;
    })();
    (function() {
        console.log(this.b); // 789
        console.log(b); // 789
        var a = 0;
        console.log(a); // 0
    })();
}
var f = new Foo();
(function() {
    console.log(this.b); // 789
    console.log(b); // 789
})();

結果:
789
789
0
789
789

情況2:

/**
 * Created by baidu on 16/10/24.
 */

function Foo() {
    (function() {
        this.b = 789;
    })();
    (function() {
        console.log(this.b); // 789
        console.log(b); //undefined
        var b = 0;
        console.log(b); // 0
    })();
}
var f = new Foo();
(function() {
    console.log(this.b); // 789
    console.log(b); // 789
})();

結果:
789
undefined
0
789
789

從以上對比,可以看出:

沒有加 this取值時,如果當前 {} 中不存在同名的局部變量,則等同於加 this 處理;如果當前 {} 中存在同名的局部變量,則按常規處理。
上面第二例中,b會打印出undefined,是因為在{}出現了b,並且是在后面出現的,當前還是undefined.

以上,是一些實驗結果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM