js函数、作用域、作用域链、闭包、立即执行函数

1.函数表达式

var fn = function(){};

组成形式

1.函数名称

2.参数(形参、实参)

3.返回值

2.作用域

  1. 作用域定义:变量(变量作用域又称上下文)和函数生效的区域。

  2. [[scope]]:每个js函数都是一个对象,对象中的属性有些我们可以访问,有些不可以,这些属性仅供js引擎存取,[[scope]]就是其中一个,[[scope]]存取了运行期上下文的集合。

  3. 作用域链:[[scope]]中锁存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接成为作用域链。

  4. 执行期上下文:当函数执行时,会创建一个执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行器上下文都是独一无二的,所以多次调用函数就会创建多个执行器上下文,当函数执行完毕,它所产生的执行期上下文会被销毁。

  5. 查找变量:从作用域链顶端向下查找。

2.闭包

  1. 定义:当内部函数被保存到外部时,将会生成闭包。闭包将会导致作用域链不释放内存,导致内存泄露。

function a(){

function b(){

}

return b;//保存到外部

}

var demo = a();

demo();

demo();

//a()执行的时候,会定义b,b是在a执行的时候定义,定义的时候会在aAO – >
GO,并且a执行后返回b,b被保存到外部,故这个之后aAO不会被释放,从而造成内存泄露。

  1. 闭包的作用

实现公有变量

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();

myArr0;//101

myArr1;//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()

模块化开发,防止污染全局变量

  1. 立即执行函数

针对初始化功能的函数

立即执行函数执行完就被销毁。

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+){

myarrj;

}//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++){

myarrj;

}//0 1 2 3 4 5 6 7 8 9