1.函數
定義
1.函數聲明
function test(){
函數體
};
2.函數表達式:
- 命名函數表達式
- ```java
var fn = function test(){};
- (匿名)函數表達式
-
var fn = function(){};
#### 組成形式
1.函數名稱
2.參數(形參、實參)
3.返回值
### 2.作用域
1. 作用域定義:變量(變量作用域又稱上下文)和函數生效的區域。
2. [[scope]]:每個js函數都是一個對象,對象中的屬性有些我們可以訪問,有些不可以,這些屬性僅供js引擎存取,[[scope]]就是其中一個,[[scope]]存取了運行期上下文的集合。
3. 作用域鏈:[[scope]]中鎖存儲的執行期上下文對象的集合,這個集合呈鏈式鏈接,我們把這種鏈式鏈接成為作用域鏈。
4. 執行期上下文:當函數執行時,會創建一個執行期上下文的內部對象。一個執行期上下文定義了一個函數執行時的環境,函數每次執行時對應的執行器上下文都是獨一無二的,所以多次調用函數就會創建多個執行器上下文,當函數執行完畢,它所產生的執行期上下文會被銷毀。
5. 查找變量:從作用域鏈頂端向下查找。
### 3.閉包
1. 定義:當內部函數被保存到外部時,將會生成閉包。閉包將會導致作用域鏈不釋放內存,導致內存泄露。
```java
function a(){
function b(){
}
return b;//保存到外部
}
var demo = a();
demo();
demo();
//a()執行的時候,會定義b,b是在a執行的時候定義,定義的時候會在aAO -- > GO,並且a執行后返回b,b被保存到外部,故這個之后aAO不會被釋放,從而造成內存泄露。
- 閉包的作用
- 實現公有變量
- eg: 函數累加器
function add(){ var count = 0; function demo(){ count++; console.log(count); } return demo; } var counter = add(); counter(); counter(); counter();
- 可以做緩存(存儲結構)
多個函數被保存為一個函數的閉包,它們操作的是同一塊內存。- eg:eater
function test(){ var num = 100; function a(){ num++; console.log(num); } function b(){ num--; console.log(num); } return [a,b]; } var myArr = test(); myArr[0]();//101 myArr[1]();//100
function eater(){ var food = "apple"; var obj = { eatFood: function () { if(food != ""){ console.log("eating " + food); food = ''; }else{ console.log("it is empty.") } }, pushFood: function (myfood) { food = myfood; } } return obj; } var person = eater(); person.eatFood();//eating apple person.pushFood("banana"); person.eatFood();//eating banana
- 可以實現封裝,屬性私有化
- eg:Person()
- 模塊化開發,防止污染全局變量
### 4. 立即執行函數
針對初始化功能的函數
立即執行函數執行完就被銷毀。
```java
var num = (function (a,b,c){
var d = a+b+c;
return d;
}(1,2,3));
PS:只有表達式才能被執行符號執行。
var test = function(){};
test();//表達式,可以被執行。
+ function (){
console.log('a');
}();//可以執行,前面加的+讓它變成了表達式。加-也一樣的道理。
function test(){
var arr = [];
for(var i = 0;i <10;i++){
arr[i] = function(){
document.write(i+" ");
}
}
return arr;
}
var myarr = test();
for(var j = 0;j < 10;+j+){
myarr[j]();
}//10 10 10 10 10 10 10 10 10 10
//arr里面存的十個元素都是函數體,返回arr后被保存到外部,形成閉包,當myarr = test()執行的時候,arr里面存了十個函數體,最后退出test的時候i=10.當執行myarr[j]的時候,運用的是test()的執行期上下文,而test()退出時,testAO里面的i=10.故輸出了10個10.
function test(){
var arr = [];
for(var i = 0;i <10;i++){
(function (j){
arr[j] = function() {
document.write(j+" ");
}
}(i));
}
return arr;
}
var myarr = test();
for(var j = 0;j < 10;j++){
myarr[j]();
}//0 1 2 3 4 5 6 7 8 9