js作用域的销毁、不立即销毁、不销毁

JavaScript中的函数执行会形成私有的作用域。

(1)作用域的销毁

  一般情况下,函数执行形成一个私有的作用域,当执行完成后就销毁了->节省内存空间

(2)作用域的不立即销毁

function fn(){
    var i=10;
    return function(n){
    console.log(n+i++);
  }
}
fn()(15);//->先执行fn,有一个私有的变量i=10,返回一个堆内存地址 xxxfff111,我们发现这个地址还用到了一次,那么当前的这个fn形成的私有作用域(A)就不能立即销毁了,      xxxfff111(15)->输出25,A中的i变为11;当xxxfff111执行完了,发现这个地址没用了,浏览器就把A、xxxfff111都释放了

fn()(20);//->在执行fn的时候一切都从新开始了,和上面的步骤是一样的->输出30

(3)作用域的立即销毁

function fn(){
    var i=10;
    return function(n){
    console.log(n+i++);
    }
}
var f=fn();//->fn执行形成一个私有的作用域A,A中有一个私有的变量i=10,A中返回一个地址xxxfff11,被外面的f占用了,那么当前的A就不能销毁了
f(15);//->输出25,让A中的i=11
f(20);//->输出31,让A中的i=12

面试题:

// 关于内存释放的面试题
function fn() {
        var i = 10;
        return function (n) {
            console.log(n + (++i));
        }
}
    var f = fn(); //首先把fn执行,然后把执行的结果赋值给f,函数执行只要看函数里面有没有return
    f(15);    //26  //引用,执行完不会立即释放
    f(20);    //32
    fn()(15); //26  //每次执行完内存释放,作用域销毁
    fn()(15); //26
    fn()(20); //31
    fn()(30); //41
    f(30);    //43

几种不销毁常用到的形式:

(1)函数执行,返回一个引用数据类型的值,并且在函数的外面被别人接收了,那么当前函数形成的私有作用域就不在销毁了-->例如上面的案例 var f=fn();

(2)在函数执行的时候,里面的一个小函数的地址赋值给了外面元素的点击事件,那么当前小函数也相当于被外面占用了,大函数执行形成的私有的作用域也不能销毁了

//每一次循环都执行自执行函数形成一个私有的作用域(循环三次就有三个作用域,每一个作用域中都有一个i,第一个存储的是0,第二个存数的是1..),在每一个私有的作用域中都把里面的函数绑定给了外面元素的点击事件,这样的话每一次形成的作用域都不销毁了(三个不销毁的作用域)
var oLis=document.getElementsByTagName("li");
for(var i=0;i<oLis.length;i++){
    (function(i){
        oLis[i].onclick=function(){
            tabChange(i);
        }
    })(i);
}

(3)在使用setTimeout实现轮询动画的时候,我们如果move需要传递参数值,那么像下面这样的写法会行成很多的不销毁的作用域,非常的耗性能

function move(tar){
    <js code>

    //window.setTimeout(move,10); ->第二次执行move的时候我们没有给它传值(这样写不行)
    window.setTimeout(function(){
        move(tar);
    },10);//->这样写实现了,但是每一次执行定时器都会形成一个私有的所用域(匿名函数形成的)A,在A中使用了上级作用域中的tar的值,而且执行了move又形成了一个小的作用域(而在小的作用域中会使用tar的值),这样每一次定时器形成的A都不能销毁了
}
move(100);//->第一次这样执行传递100

//解决方案
function move(tar){
    (function _move(){
        <js code>
        window.setTimeout(_move,10);
    })();
}
move(100);//->第一次这样执行传递100

JS中内存空间释放的问题(堆内存、栈内存)

[谷歌浏览器]
我们开辟一个内存,可能或有一些其他的变量等占用了这个内存,谷歌浏览器都会间隔一段时间看这个内存还有没有被占用,如果发现有没有被占用的内存了,就自己帮我们回收了(内存释放)

[火狐和IE]
我们开个内存,当我们引用了它,就在内存中记录一个数,增加一个引用浏览器就把这个数+1,减少一个引用,浏览器就把这个数-1...当减到零的时候浏览器就把这个内存释放了;但是有些情况下(尤其是IE)记着记着就弄乱了,内存就不能释放了-->浏览器的内存泄露

var obj={};
我们养成一个好的习惯,当我们obj这个对象使用完成了,我们手动的obj=null (null空对象指针),浏览器会自己把刚才的堆内存释放掉

参考:关于JS中作用域的销毁和不销毁的情况总结

时间: 2024-10-07 05:24:58

js作用域的销毁、不立即销毁、不销毁的相关文章

js作用域链 js没有块级作用域

arguments和函数内定义的变量或函数->父级->下一个父级->.....->全局环境中的变量或函数 if(true){ var a=1; } console.log(a);js没有块级作用域, 变量a直接添加到当前的执行环境中.  java有块级作用域,if语句结束后会销毁if中定义的变量

关于js作用域

我们知道在编程语言中,作用域的作用就是控制变量.参数的可见范围和生命周期. js中提供了函数作用域的功效,比如在函数中定义的变量外部是无法访问到的: function jsFunc(){ var a = 5; } alert(a); // undefined 但是js中却没有提供块作用域的功效,比如我们在java代码中如果些如下代码: public static Boolean b = false; public static void main(String[] args) { if(!b){

js作用域理解 function(){} var

在coding过程中遇到过下面的情况: 1 var test1 = function(){ 2 var c=4; 3 test2(); 4 }; 5 6 var test2 = function(){ 7 console.log(c); 8 }; 9 10 test1(); 思考一下,7行会conasole出什么?4 吗?实际上却是 c is not defined. 而当代码如下的时候, 1 var test1 = function(){ 2 var c=4 3 var test2 = fun

js作用域的几个问题

按照<权威指南>的说法,全局的变量作用域是全局性的,在js代码中,他处处都有定义.而在函数之内声明的变量,就只有在函数体内有定义了.函数的参数也是局部变量,他们只在函数体内部有定义.在函数体内部,局部变量的优先级比同名的全局变量高.如果给一个局部变量或函数的参数声明的名字与全局变量的名字相同,那么就有效地隐藏了这个全局变量. js没有块级作用域,,函数中声明的所有变量,无论在哪里,如for ,if等,在整个函数中他们都是有定义的.这个也叫变量提升,作用域都是在函数中. 1,对象内部的作用 ?

JS作用域链

Js作用域与执行环境: 1. 作用域链: <1>用途:保证对执行环境有权访问的所有变量和函数的有序访问. <2>构成: a.作用域链的前端,始终都是当前执行代码所在环境的变量对象(如果这个环境是函数,则将其活动对象作为变量对象,活动对象在最开始时只包含一个变量,即arguments对象): b.下一个变量对象来自包含(外部)环境: c.最后一个对象,为全局执行环境的变量对象. <3>标识符解析:是沿着作用域链一级一级地搜索标识符的过程,始终从作用域链的前端开始,然后逐级

JS作用域面试题总结

关于JS作用域问题,是面试的时候面试官乐此不疲的面试题,有时候确实是令人抓狂,今天看到一个讲解这个问题的视频,明白了那些所谓的“原理”顿时有种豁然开朗的感觉~~~ 1.js作用域(全局变量,局部变量)内部可以访问外部,但外部的不能访问内部的(局域变量) var a=10; function aaa(){ alert(a); }; aaa(); //a 为外部变量即全局变量,所以可以直接访问到 结果为10 function aaa(){ var a=10; }; aaa(); alert(a);

基础知识回顾——js作用域

1.对js作用域的理解. 作用域 作用域分为全局作用域和函数作用域,我们可以理解为变量的生存环境(空间).全局作用域包含函数作用域,函数作用域里的变量可以访问到全局作用域中的变量,但是反之则不行. 变量提升 在js作用域中还有变量提升的现象(只有var 声明的变量才会有变量提升,window声明的不会),赋值语句最后生效.当我定义一个变量,如果它没有被赋值,它是属于undefined: 变量提升的优先级 函数声明 > 函数形参(函数的形参属于函数作用域:) > 自定义变量 延长作用域,闭包(r

闲话js作用域

js词法环境包括环境变量绑定及外部引用'函数创建的时候有个内部属性[[scope]],它指向当前函数的词法环境对象.而词法环境的外部引用一个词法环境'直到全局词法环境'它外部引用为null'这样就构成作用域链.当进入可执行代码时'会创建执行环境'执行环境包括词法环境变量环境及this关键字绑定'如果是函数'它还会创建一个新的词法环境对象添加到当前作用域链前端'此为活动对象'活动对象的外部引用为此前的最上层执行环境' 闲话js作用域

easyui datagrid load 封装 参数问题 js 作用域

var temp = { LoginAccount: $('#LoginAccount').val(), ShopName: $('#ShopName').val() }; function doSearch1() { $('#datagrid').datagrid('load', temp); } function doSearch2() { $('#datagrid').datagrid('load', { LoginAccount: $('#LoginAccount').val(), Sh