懵逼的JavaScript大白(三)——函式
一、宣告方式
1、函式宣告語句
function fun () {}
2、函式表示式
var fun = function () {};
3、建構函式建立方式(以後不會使用這種方式)
var fun = new Function('x', 'y','console.log(x, y);');
fun(100, 200);
二、屬性
1、length屬性:用於獲取形參個數
function fun (x, y, z) {}
console.log(fun.length);
2、caller屬性:用於獲取函式的呼叫位置
全域性中呼叫時,返回null
某個函式中呼叫時,返回這個函式fun2的函式體。
function fun () {
console.log(fun.caller);
}
function fun2 () {
fun();
}
fun2();
3、prototype屬性:只有建構函式才使用這個屬性
4、arguments屬性:這個屬性已經不推薦使用了,而是推薦使用函式內的arguments偽陣列物件
function fun () {
console.log(arguments);
console.log(fun.arguments);
}
fun(100, 200, 300);
① arguments物件
偽陣列結構:具有索引和長度,沒有陣列方法
作用:用於獲取函式本次呼叫時傳入的所有實參
function fun () {
console.log(arguments);
}
fun();
② arguments.callee屬性:用於獲取當前函式
function fun () {
console.log(arguments.callee);
}
fun();
三、方法
① call() - 用於呼叫函式,同時可以修改函式內的this
② apply() - 用於呼叫函式,同時可以修改函式內的this
引數1:用於設定當前函式本次呼叫時的this值
引數2:陣列結構,用於儲存所有要傳入的實參
function fun (n, m) { console.log(this); console.log(n, m); } fun(100, 200); fun.call({name : 'jack'}, 'abc', 'efg'); fun.apply({name : 'rose'}, ['引數1', '引數2']);
③ bind() - 用於繫結函式副本中的this和某些實參
引數1:用於繫結函式副本中的this,並且不可修改
後續引數:用於繫結函式副本中的某些實參
如果在函式副本中傳入實參表示設定繫結的實參後續的其他實參。
返回值:當前函式的副本
function fun (num1, num2, num3) {
console.log(num1, num2, num3)
}
// 傳入null,this預設為window
var result = fun.bind(null, 100, 300);
result();
result(900);
四、使用方式
1、 普通使用方式: 函式宣告語句,函式表示式
① 預解析階段的提升方式不同。
② 在特殊場景中使用時,不同的形式在不同的瀏覽器中效果有所不同
2、 立即執行函式(自呼叫函式)
① 內部可以使用匿名函式或命名函式,但是通常使用匿名函式。
② 語法形式:(function () {})();
③ 使用方式:每個獨立功能外面包裹一個立即執行函式即可。還需要設定兩個引數,window,document,固定用法
④ 作用
1. 減少全域性變數的使用
2. 減少作用域的訪問次數
3. 進行模組化操作
3、 回撥函式(將函式作為引數使用)
① 含義:將函式作為引數使用
② 使用場景:當某個函式中的功能程式碼不確定時可以使用函式引數(包裹)
4、 將函式作為返回值使用(用於解決閉包的問題)
閉包概念:一個可以對私有變數進行操作的函式稱為閉包函式
使用的好處:實現資料的私有化,增強資料的安全性。由於對私有變數進行操作的方式是我們提前設定的,所以使用者無法進行任意修改。
注意:不要濫用閉包函式。
普通的函式每次呼叫時不相關聯的,當某個函式呼叫完畢後,作用域會被銷燬,內部的變數和函式都被銷燬。當我們使用閉包函式時,由於私有變數可以被外界進行持續操作,這個私有變數在函式呼叫完畢也不會進行銷燬。
var arr1 = [1, 2], arr3 = [3, 4], arr4 = [5, 6];
function fun () {
// sum是一個私有變數,無法被外界直接操作
var sum = 0;
// 在fun內部指定一種對sum這個私有變數的操作方式
// 對某個陣列進行求和,並且將所有的和累計在sum中
return function (arr) {
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
console.log(sum);
};
}
// 呼叫fun,接收閉包函式,命名為getSum,通過對getSum的使用,將每個陣列的和累計在私有變數sum中
// 確保了資料的安全
var getSum = fun();
getSum(arr1);//3
getSum(arr3);//10
getSum(arr4);//21
5、遞迴函式
1 基本概念:函式內呼叫當前函式
2 遞迴可能出現的問題:
① 無限的呼叫(死迴圈)
② 執行的效率問題
3 解決方式:給遞迴函式設定結束條件
① 計數法:使用較少,因為for迴圈更簡單
② 根據功能的規律設定結束條件
//斐波那契數列:1 1 2 3 5 8 13 21 34 55 89 144
function getFb (n) {
if (n === 1 || n === 2) {
return 1;
}
return getFb(n - 1) + getFb(n - 2);
}
console.log(getFb(12));
③ 執行效率問題:由於遞迴呼叫重複執行,可能會導致某些值進行多次的重複計算,而這些重複計算是沒有意義的
var obj = {};
function getFb (n) {
if (n === 1 || n === 2) {
return 1;
}
return obj[n] ? obj[n] : obj[n] = getFb(n - 1) + getFb(n - 2);
}
console.log(getFb(12));