老徐WEB:js入門學習 - javascript函數和閉包

函數是一段可以重複執行的代碼塊。

比如我們經常會做這樣的事,通過標籤ID獲取元素對象,javascript語句是document.getElementById('demo')。我們就可以把這一句寫成一個函數,傳遞的參數就是標籤ID的值,然後返回元素對象。

把重複做的事情,寫成一個函數,下次再碰到同樣的事情,直接調用函數即可,不用再重複寫一堆同樣的代碼的。函數內的代碼功能不要太複雜,如果複雜了,就可以把代碼塊分成多個函數,儘量讓一個函數只做一個事情。

下面介紹函數的聲明、參數、調用。


函數聲明

javascript中使用關鍵字function聲明函數。
聲明函數的方式有如下幾種:

函數聲明

function functionName(parameters){
	// 代碼塊
}

這是函數的聲明,不是執行語句,所以最後沒有分號結束。這個方式定義的函數可以在聲明前調用函數。

 

函數表達式

var x = function(parameters){
	// 代碼塊
};

這是一個執行語句,所以最後以分號結束。這個方式定義的函數不可以在定義前調用函數。函數存儲在變量中,不需要函數名,通過變量名來調用函數,這也是匿名函數。

 

Function構造函數

var functionName = Function(a,b){
	// 代碼塊
};

這個方式不常用,類似函數表達式的方式。

 

自調用函數

(function(){var x = 'Hello !!'})();

自調用函數是一個表達式,表達式後面緊跟(),最後以分號結束,這樣在瀏覽器加載頁面時會自動調用函數。

 

箭頭函數

(參數1,參數2,,,參數n)=>{函數體}
當只有一個參數時,圓括號是可選的,當沒有參數時,圓括號保留。
ES6增加了箭頭函數,其表達式語法比普通函數語法要簡單。

對比一下ES5與ES6的函數聲明方式

ES5的普通函數

var x = function(x,y){
	return x * y;
}

 

ES6的箭頭函數

const x = (x,y) => {return x * y};

如果函數體只有一條語句,可以省略return和{}
如果箭頭函數直接返回一個對象,必須在對象外加上圓括號。

const x = id => ({id:id,name:'tmp'})

 


 

函數參數

函數參數分爲顯式參數和隱式參數。

顯式參數

function x(parameter1,parameter2,parameter3,,,){
	// 執行代碼塊
}

 

在這裏有個需要注意的點就是,參數的默認值。因爲聲明函數時,可能帶有多個參數,但不是所以參數都會在函數調用時被傳值,所以在不確定會被傳值的參數給出默認值。

function x(parameter1,parameter2=0){
	// 執行代碼塊
}

 

隱式參數

隱式參數是arguments對象,就是在函數體內通過arguments對象來獲取調用函數時傳遞的值。

x(2,3,45,6); // 函數調用,且傳遞參數
function x(){ // 函數聲明
	y = arguments[0];
}

 

函數調用

javascript函數調用有4種方法。

 

作爲一個函數調用

function myFunction(a,b){
	return a + b;
}
myFunction(10,20); // 函數調用

 

函數作爲對象方法調用

var myObject = {
	firstName:'A',
    lastName:'a',
    fullName:function(){
    	return this.firstName+this.lastName;
    }
}
myName = myObject.fullname(); // 作爲對象方法調用

 

使用構造函數調用函數

function myFunction(a,b){
	this.firstName = a;
    this.lastName = b;
}
var x = new myFunction('A','a');
x.firstName;

 

作爲函數方法調用函數

call() 和 apply() 是預定義的函數方法。 這兩個方法可用於調用函數,兩個方法的第一個參數必須是對象本身。

function myFunction(a,b){
	return a + b;
}
myArray = [1,2];
var myObject = myFunction.apply(myObject,myArray);

 

閉包

閉包相關的知識點有
1.變量作用域
2.函數嵌套
3.函數自調用

閉包的特點有
1.可以在函數外操作函數內的私有變量
2.可以使變量常住內存

 

通過前面的學習,我們知道javascript的變量作用域有全局和局部之分。具體是函數外部的變量是全局變量,函數內部的變量是局部變量。

函數的嵌套到現在來說是第一次碰到。不過如果你學過其他編程語言的話,對嵌套應該很熟悉了。

函數的嵌套就是函數裏面套着一個函數,像下面這樣。

function test(){
	function test1(){}
}

 

前面也說到函數自調用了,這裏不再說了。

 

下面繼續說,全局變量是任何函數都可以操作的,如果想佔爲已有,只讓自己操作,那是不能的。而局部變量只能在函數內部操作,在函數外部是不能操作的,那麼有沒有一種可能就是在函數外部操作函數內的變量呢。

 

函數嵌套就可以解決這個問題,在外部函數內聲明一個局部變量和一個內嵌函數,這個變量在外部函數內部,只有自己能操作,同時又在內嵌函數的外部,所以內嵌函數也是可以操作這個變量的。

 

通過外部函數自調用,返回內嵌函數表達式,然後在外部(全局作用域)調用內嵌函數,這樣就能在外部(全局作用域)通過內嵌函數來操作局部變量了,這就是閉包。

 

<button type="button" id="btn">計數</button>
<p id="demo">0</p>
<script>
var add = (function () { // 匿名函數
    var counter = 0; // 是局部變量,對於內嵌函數來說又是全局變量,所以內嵌函數能操作這個變量
    var addIn = function () {return counter += 1;} // 內嵌函數聲明
	return addIn; // 返回了內嵌函數表達式,並賦值給變量add
})(); // 匿名函數自調用
document.getElementById('btn').οnclick=function(){
	document.getElementById("demo").innerHTML = add(); // 在外部調用返回的內嵌函數,達到在函數外部操作函數內變量的目的。
}
</script>

 

勤學苦練,笨鳥先飛。關注【老徐WEB前端開發教程】公衆號,聽老徐說。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章