由javascript中”匿名函數調用寫法”引出的一些東東

來源:互聯網
上載者:User

匿名函數自動調用的三種寫法如下:

var f1 = function(){alert("f1");}();(function(){alert("f2");}());void function(){alert("f3");}();

再來看一段代碼:

function Person(properties){for(var p in properties){(function(context){var t = p;context["get" + t] = function(){return properties[t];}context["set" + t] = function(val){properties[t] = val;}}(this));}}var p = new Person({name:"菩提樹下的楊過",sex:"男"});alert(p.getname());//彈出"菩提樹下的楊過"alert(p.getsex());//彈出"男"alert(p.name);//彈出:undefined

Person類為所有傳入的對象屬性,自動產生了getXXX與setXXX方法,這一段代碼雖然很短,卻包含了諸多js中的關鍵概念:

1.json對象標記法

當我們把"{name:"菩提樹下的楊過",sex:"男"}"做為參數,傳入Person建構函式時,實際上就建立了一個字典結構的索引值對:

name --> "菩提樹下的楊過"
sex --> "男"

即  name - value 結構,所以也就能用for ...in語句來遍曆了

以上結論,可以這樣測試

var obj = {name:"菩提樹下的楊過",sex:"男"};for(var p in obj){    alert("名稱:" + p + ",值:" + obj[p]);}

2.匿名函數的自動調用

這一段代碼結構可以簡化為:

function Person(properties){for(var p in properties){        (        function(){        ...      }()      );  }}

可以看到,裡面其實就是調用了匿名函數(即文章最開頭的第二種寫法)

3.函數調用時的上下文關係

每個函數調用時總會關聯一個上下文(如果找不到上下文,則最終會關聯到window對象)

function foo(fn){    //this.barbar = "Foo.barbar"; if (typeof fn === "function"){  fn(); } }var bar = { barbar : "Hello,World!", method:function(){      alert(this.barbar); }}bar.method(); //調用時,medhod中的this指的就是bar對象的上下文,此時this.barbar 與 bar.barbar等效  foo(bar.method);//調用時,這時bar.method中的this指代的是foo內部的上下文,而foo中並沒有barbar的定義,因此最終this.barbar其實就是foo.barbar,所以會彈出"undefined",如果把foo中的注釋行去掉注釋,就更能映證這一點

這是最近網上熱傳的"javascript令人費解的10件事"中的一段代碼,我在注釋中加了自己的理解,再回到文中的代碼,代碼的本意是想讓Person類動態添加對所有的屬性的getXXX與setXXX方法(通過匿名函數的自動調用),而匿名函數在執行時getXXX與setXXX函數的上下文this預設是指向匿名函數的,而非Person類本身!為瞭解決這個問題,不得不在匿名函數中增加了一個參數context,並且在調用時用(function(...){}(this));把Person的上下文this傳入到匿名函數中

4.閉包
關於閉包,不再做過多的學術解釋,先給一段代碼:

<ul> <li id="a1">aa</li> <li id="a2">aa</li> <li id="a3">aa</li></ul><script type="text/javascript">for (var i=1;i<= 3;i++){ var li = document.getElementById("a" + i); li.onclick = function(){  alert(i); }}</script>

解釋onclick產生了一個匿名函數,並引用外層的變數i,形成閉包,造成變數i在該函數中共用(可以理解為三個li的onclick函數中都引用同一個變數i),而i在迴圈結束後,變成4,因此所有li最終點擊都是彈出4

解決辦法:

<script type="text/javascript">for (var i=1;i<= 3;i++){ var li = document.getElementById("a" + i); li.i = i; li.onclick = function(){      alert(this.i); }}</script>

再回到文中的代碼,同樣匿名函數引用外層的變數p,形成閉包,如果不用var t = p;中轉一下變數,則最後所有的getXXX與setXXX方法,都是對應最後一個屬性的.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.