天天看點

JS函數(自調函數)與閉包【進階函數】

JavaScript:BOM(浏覽器對象)+DOM(文檔對象)+ECMAScript

javascript面向對象:

  * 概述:

  * 發展:

  * 網際網路發展對浏覽器頁面性能或效果要求越來越高,HTML(XHTML\DHTML)及javascript等技術發展.

  * 行業标準發展,推動javascript的要求越來越高.

  * 工作内容:

  * 對用戶端邏輯處理越來越高.

* 概念:

  * 面向對象:這個人就是對象,年齡、性别、學曆等叫做屬性,出生、上學、結婚等叫做方法(函數).

  * 類、對象、繼承、重載、重寫等.

  * 類:例如女生就是一個類.

  * 對象:例如範冰冰就是一個對象.

  * 面向過程:這個人出生、長大、上學、功能、結婚、生子、去世.

  * 注意:javascript是不存在類的概念.

* 開發工具:

  * MyEclipse或Eclispe都需要掌握.

  * WebStrom:在國内,号稱是前端開發神器.

------------------------------------- 函數:------------------------------

  * 定義函數的三種方式:

    * function 函數名(){}

    * var 函數名 = function(){}

    * var 函數名 = new Function();

  * Arguments對象:

    * 模拟函數的重載效果.

* 特性:

  * Arguments對象内部應該是一個數組結構.

  * Arguments對象的length屬性:可以擷取目前函數的實參個數.

* 變量的作用域:

  * 分類:

    * 全局域 - 全局變量

    * 局部域(函數域) - 局部變量

  * 特殊情況:

    * 定義局部變量時,不使用"var":局部變量自動被定義為全局變量.

    * 全局變量與局部變量同名時:在函數域中隻能通路局部變量.

第一種情況:

  函數内部通路全局變量

第二種情況:

  全局變量與局部變量同名時:在函數域中隻能通路局部變量.

第三種情況:

   定義局部變量時,不使用"var":局部變量自動被定義為全局變量.

第四種情況:

  提示undefined:存在變量,值為空(類似于java的隻定義未初始化)

  報錯未定義:不存在變量

 第五種情況:方法内部改變全局變量值

  

* 特殊函數:

  * 匿名函數:沒有名的函數

    * 将匿名函數作為參數傳遞給另一個函數.

    * 利用匿名函數來執行一次性任務.

第一種:

  将匿名函數作為參數傳遞給另一個函數.

第二種

  利用匿名函數來執行一次性任務.(自調函數)

上面隻是手動的設定調用函數一次,可以被重複調用,為了希望函數隻被調用一次,可以用自調函數。(頁面加載後執行一次,不可以被重複調用)

自調函數(自己調用自己,隻能執行一次,重要)

  * 回調函數:

    * 匿名回調函數 

   * 自調函數

    * 第一個小括号:定義函數

    * 第二個小括号:調用函數(傳參)

  * 内部函數(私有函數)

    * 在一個函數中,定義另一個函數.

    * 類似于Java中的内部類.

        解決目前特定需求,代碼安全性

  * 傳回函數的函數:内部函數的一種特殊用法.

   平行函數可以通過内部函數通路到其局部變量,先擷取到n(),再通過n()擷取。

* 預定義函數(全局對象):

  * escape()函數:将字元串内容進行轉義.

  * eval()函數:将字元串内容進行轉義.

  * Number()函數:将字元串内容轉換成數字,多與isNaN()函數配合使用.

  * parseFloat()或parseInt()函數

  * String()函數

-------------------------------- 閉包--------------------------

是不是閉包條件:

(1)全局域中通路局部函數n()——其上一層函數為fn()

(2)函數n()可以通路fn()變量

(3)函數fn中的局部變量位置不能改變

  * 閉包的概念,在目前階段極其重要.閉包,指的是詞法表示包括不被計算的變量的函數,也就是說,函數可以使用函數之外定義的變量。

  *閉包的兩個重要作用:一個是前面提到的可以讀取函數内部的變量,另一個就是讓這些變量的值始終保持在記憶體中。

* 對象:

* 原型:

* 原型的應用,在目前階段及其重要.

* 繼承:

 1.函數的作用鍊:變量的作用域具有傳遞性

2.閉包:(作用是降低函數之間的耦合性,類似于java中的解耦——繼承,接口)

 3.循環中閉包:

4.利用閉包實作getter,setter(頁面初始化執行一個函數給變量指派)

5.利用閉包讓局部變量儲存在記憶體中

JS函數(自調函數)與閉包【進階函數】
JS函數(自調函數)與閉包【進階函數】

   在這段代碼中,result實際上就是閉包f2函數。它一共運作了兩次,第一次的值是999,第二次的值是1000。這證明了,函數f1中的局部變量n一直儲存在記憶體中,并沒有在f1調用後被自動清除。

  為什麼會這樣呢?原因就在于f1是f2的父函數,而f2被賦給了一個全局變量,這導緻f2始終在記憶體中,而f2的存在依賴于f1,是以f1也始終在記憶體中,不會在調用結束後,被垃圾回收機制(garbage collection)回收。

  這段代碼中另一個值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒有使用var關鍵字,是以 nAdd是一個全局變量,而不是局部變量。其次,nAdd的值是一個匿名函數(anonymous function),而這個匿名函數本身也是一個閉包,是以nAdd相當于是一個setter,可以在函數外部對函數内部的局部變量進行操作。

  1)由于閉包會使得函數中的變量都被儲存在記憶體中,記憶體消耗很大,是以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導緻記憶體洩露。解決方法是,在退出函數之前,将不使用的局部變量全部删除。

  2)閉包會在父函數外部,改變父函數内部變量的值。是以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把内部變量當作它的私有屬性(private value),這時一定要小心,不要随便改變父函數内部變量的值。

最後附幾個自己寫的簡單的閉包:

參考:http://www.cnblogs.com/xdp-gacl/p/3703876.html

補充:JS自調函數的幾種寫法:

【當你用心寫完每一篇部落格之後,你會發現它比你用代碼實作功能更有成就感!】

js