5.1 引用類型之 function

function類型:

1.函數初認識

函數實際上是一個對象,對象就和其他引用類型一樣,具有屬性和方法。由於函數是一個對象,所以函數名是一個指向函數對象的指針,不會與某個函數綁定。

var sum = function(num1, num2){
return num1 + num2;
};

在使用函數表達式時,沒有必要使用函數名,通過變量sum就可以引用函數,注意末尾有分號。
還有一種是使用構造函數,Function,接收任意數量參數,但最後一個是函數體。

var sum = new Function("num1", "num2", "return num1 + num2"); // 不推薦

不過這種寫法對於理解函數是對象,函數名是指針比較好。
因此,函數沒有重載概念。

2. 兩種函數定義方式

解析器在想執行環境中加載數據時,對函數聲明和函數表達式的操作不一樣。解析器會先讀取函數聲明,使得它在執行任何代碼前可用,這個過程叫函數聲明提升。函數表達式則會等到執行到它是纔會被解釋執行。

3.函數內部屬性:

函數內部,有兩個特殊對象:arguments和this。arguments是一個類數組對象,包含傳入函數的所有參數,它的主要作用是保存函數,但他有一個callee屬性,該屬性是一個指針,指向擁有這個arguments對象的函數,
例如:定義一個階乘函數:

/*階乘函數*/
			function factorial (n) {
				if (n === 1) {
					return 1;
				}
//				return n * factorial(n-1);
				return n * arguments.callee(n-1);
			}
			var result = factorial(4);
			console.log(result);

優點:無論引用函數時使用的是啥名字,都可以保證正常完成函數遞歸調用。

關於this:this引用的是函數據已執行的環境對象,也可以說是this值,當在網頁的全局作用域中調用函數時,this對象引用的就是window。

window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor;//給o增加一個方法,
o.sayColor(); //"blue",此時this指向O這個對象。

在函數調用之前,this的值並不確定,因此this可能會在代碼執行過程中引用不同的對象,
與callee一起的還有一個caller,該屬性返回的是調用該函數的函數。
注意一點,在嚴格模式下,callee會報錯;不能爲caller屬性賦值。

4. 函數屬性和方法:

每個函數包含兩個屬性:length和prototype
length表示希望接收參數的個數。
對於所有的引用類型,prototype是保存他們所有實例方法的所在。換句話說,諸如toString()和valueOf()等方法實際上都保存在prototype名下,只不過是通過各自對象的實例訪問罷了。在創建自定義引用類型以及實現繼承時,prototype屬性的作用極爲重要,在ES5中,prototype屬性是不可枚舉的,因此使用for-in無法發現。

每個函數包含兩個方法:apply() 和call()
這兩個方法的用途都是在特定的作用於在調用函數,實際上就是設置函數體內this對象的值。首先apply() 方法接收兩個參數,一個是在其中運行函數的作用域,另一個是參數數組。第二個參數與可以使Array實例,也可以是arguments對象。

function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments); // 傳入 arguments 對象
}
function callSum2(num1, num2){
return sum.apply(this, [num1, num2]); // 傳入數組
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20

傳遞參數並不是他們的主要用途,他們的強大之處在於擴充函數賴以運行的作用域。

window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue

當調用sayColor.call(o) 時,函數的執行環境不一樣了,,此時函數體內部的this指向了O,於是結果顯示爲blue。
使用他們的好處是,對象不需要與方法有任何耦合關係,二可以直接調用方法。
ES5中還定義了一個方法: bind() ,這個方法會創建一個函數的實例,其this值會被綁定到傳給bind()函數的值:

window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue

在這裏,sayColor()調用bind()方法,傳入對象O,創建了objectSayColor()函數,objectSayColor()函數的this值等於O,因此在全局作用域中調用這個函數,也會看到blue。

5.基本包裝類型:

爲了便宜操作基本類型值,ES5引入了3個特殊的引用類型:Boolen Number String 。

var s1 = "some text";
var s2 = s1.substring(2);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章