• 谈一谈js的内存分配


      因为js是一门动态语言,动态分配内存的方式让使用者运用快速便捷,却忽略了他的内存分配机制,今天我来试着理清思路。

      还是那个惯例,从基础讲起,然后发散思维,由浅入深。

      JavaScript有两种变量类型,原始值和引用值。原始值指的是原始数据类型,分别为undefined,null,number,string,boolean类型。引用值指的是复合数据类

    型,即Object、Function、Array。

     原始值和引用值存储在内存的位置分别为栈和堆。原始值是存储在栈中的简单数据段,它们的值存储在变量访问的位置。引用值是存储在堆中的对象(存储在栈

    中的只是一个指针,指向存储在堆中的实际对象)。

     基础都很简单,但是要活用,然后我们看一个闭包的例子:

    for(var i=0,arr=[];i<=3;i++) {  
      arr.push(function(){  
        alert(i);  
      });  
    }   
    arr[0](); // 4  
    arr[1](); // 4 

        关于这个经典闭包的例子,看了很多的解释,但我认为还是从内存的角度来解析最好,我们来活学活用。

    (1)预解析,i,arr,匿名函数

    (2)从上而下解析,i=0,arr[0]=匿名函数

    (3)i=1,arr[1]=匿名函数

    (4)i=2,arr[2]=匿名函数

    (5)i=3,arr[3]=匿名函数

    (6)i=4,循环结束

    (7)执行arr[0],因为存入arr内的匿名函数其实是个指针,所以现在才开始执行匿名函数,此时i为4

    (8)同理,arr[1]==arr[2]==arr[3]==4

    其实在(1)时,i为undefind,而arr数组和匿名函数都是个指针,后续慢慢为arr数组开辟了内存空间,里面存入了匿名函数的指针



      既然你都知道了原理抓住了命门,那怎么解决是不是很简单了。

      所以解决闭包问题,我们有很多思路,可以让匿名函数即刻执行保存结果,也可以把当前循环时i的值保存在函数里等等。

      这里随便列几个供参考,思路可能还有很多

    (1)

    for(var i=0,arr=[];i<=3;i++) {  
        arr.push(function(i){  
            alert(i);  
        })(i);  
    }  

    这是让匿名函数即刻执行保存结果,注意这几个i的含义,传入参数i与变量i

    (2)

    for(var i=0,arr=[];i<=3;i++) {  
      let a = i;   
      arr.push(function(){  
        alert(a);  
      });  
    }   

    这是把当前循环时i的值保存,let是ES6新语法

  • 相关阅读:
    CobaltStrike上线Linux主机(CrossC2)
    Active-Directory活动目录备忘录
    CVE-2020-5902 F5 BIG-IP 远程代码执行漏洞复现
    SSTI-服务端模板注入漏洞
    powershell代码混淆绕过
    绕过PowerShell执行策略方法
    "dpkg: 处理归档 /var/cache/apt/archives/libjs-jquery_3.5.1+dfsg-4_all.deb (--unpack)时出错"的解决方法
    firda安装和使用
    内网渗透-跨域攻击
    Web-Security-Learning
  • 原文地址:https://www.cnblogs.com/ZpandaZ/p/7397027.html
Copyright © 2020-2023  润新知