js中函数(function)的内存分布/执行顺序/作用域链/生命周期

责编:menVScode 2017-08-29 0:11 阅读(1324)

        作用域:对某个变量或者属性具有访问的权限。局部作用域是通过 function来进行声明的,把定义在function里的变量成为局部变量,只能在其内部访问。但是声明不等于创建,只有当他被调用的时候才会创建。

        function局部作用域是怎么创建的/为什么访问不到局部变量?

        首先在堆中通过function声明了fn函数,并开辟了一块内存空间,函数的声明都会有一个名字,而这个名字在当前的内存里面,是一个引用的名称。但引用名称不等同与内存地址,可以通过引用名称找到这块内存。局部作用域通过 function来进行声明,但是声明不等于创建,只有当他被调用的时候才会创建。

        当函数被声明的时候,其当前的内存空间是一个“空壳子”。

QQ截图20170828222018

        当在运行时环境调用fn()函数,它会进入到当前的fn所在的内存空间,在这里面开辟一块临时的内存空间。同时也会有堆和栈的分布,常量池是内存中唯一的公共区域。当调用调用结束后,就会销毁这块临时内存空间,也就访问不到函数里面的变量了。

function fn(){
     var a = 1;
}
fn();
console.log(a);

QQ截图20170828224057


        变量的就近原则/作用域链/生命周期

        就近原则:如果函数自身的局部作用域有声明这个变量,那就不会去上一层的作用域里去找了。

        作用域链:如果局部作用域找不到所声明的变量,然后会去上一层的作用域去找。

        全局变量生命周期:全局作用域中,关闭浏览器进程内存空间回收他随之也被回收。

        局部变量生命周期:定义在函数中,调用即存在,调用完毕即销毁。        

var a=10;
function(){
     console.log(a);
     var a=1;
     console.log(a);
}
fn();

QQ截图20170828231400


        函数执行规则 (函数声明、函数表达区别

function fn1(){  //函数声明
     console.log(1)
};

fn2(); // 2:调用fn2函数,然而找不到fn2
var fn2 = function(){ //函数表达式,执行代码   1:定义fn2
     console.log(1)
};
//fn2(); //将调用函数的代码放在函数表达式后面,才不会报错。

         只要是函数声明,在内存中就一定会有一个引用名称。

//var fn = {};
function fn(){ //函数声明
     console.log(1)
};

var fn = function(){ //函数表达式
     console.log(2)
};
fn();//最终结果为2

        首先在堆中声明fn函数,并开辟内存空间;在栈中声明变量fn。接下来是执行代码,发现有一个逆名函数,也会在堆中创建内存空间,但逆名函数根本没有引用名称,有内存地址,然后把内存地址给到变量fn。

        当在运行环境时调用fn()函数,首先会去栈中检索有没有定义fn的变量;

        若有: 根据fn变量存储的内存地址找到对应的内存空间;若fn变量没有存储内存地址,就去堆中找fn的引用。(这种现象:是将上述的代码fn()放在函数声明代码和函数表达式代码中间)

        若没有: 堆中找fn的引用。

        注意:假如找到的变量fn不是保存着函数的内存地址,而是对象的内存地址,则fn()的执行结果会报错。

QQ截图20170828235019

        为什么不先去堆中找?

        在内存中,栈所占用的空间是非常非常小的区域,相反堆占的比较大。

标签: function 函数 js
前端交流群: MVC前端网(menvscode.com)-qq交流群:551903636

邮箱快速注册

忘记密码