阅读 225

JavaScript-变量,作用域与内存问题

ECMAScript 定义变量包含两种不同的数据类型的值

基本类型值 简单的数据段

  • Null, Undefined,String, Boolean, Number

  • 按值访问

  • 复制

    • 基本类型的复制后,值是独立的

      var n=5//独立
      var m =n//独立
      m=4//不影响n复制代码

引用类型的值,可能由多个值构成的对象

  • 值是内存中的对象,按引用访问

  • Javascript不允许直接访问内存中的位置,也就是说不能直接操作内存空间,操作的是对象的引用,不是实际对象

  • 可以添加,改变,删除属性,方法

    var p = new Object();
    p.name='haha';
    console.log(p.name)//'haha';复制代码
  • 复制

    • 实际是一个指针,指向内存中堆的一个对象,两个变量实际上引用同一个对象

      var oj1=new Object();
      var oj2=oj1;
      oj1.name='d'
      console.log(oj2.name)//d复制代码

传递参数

ECMAScript中所有函数的参数都是按值传递的

就是函数的外部的值,复制给函数内部的参数

  • 基本类型,如复制值,函数内外独立

  • 引用类型,会把内存中的地址复制给函数内部的一个局部变量,局部变化可以反应到外部

function add(num){
    num +=10;
    return num;
}
var c = 20;
var r=add(c);
console.log(c)//20

function setName(obj){
    obj.name='e';
}
var person = new Object();
setName(person);
console.log(person.name);//e复制代码

为何说参数是按照值传递的

function setName(){
    obj = arguments[0]//复习函数章节,arguments对象
    obj.name='N';//反应到a对象,添加了name属性,值为N
    obj = new Object();
    obj.name='G'
}
const a = new Object();
setName(a);
console.log(a.name)//N复制代码

实际函数内部修改了obj对象,但是原始的a对象的引用没有发生改变, obj变成了局部变量,函数执行完毕后obj被销毁。

执行环境及作用域

  • 每个执行环境都有一个与之关联的变量对象

  • 环境中所有的变量和函数都保存在这个对象中

  • Web浏览器,全局执行环境是window对象

  • 环境中所有代码执行完毕后,环境会被销毁,其中的变量,函数也被销毁

  • 环境栈

    • 每个函数都有自己的执行环境, 全局或局部

    • 执行一个函数会被推入一个环境栈中,执行后,环境弹出栈,控制权交给之前的执行环境(ECMAScript 程序中的执行流)

  • 当代码在一个环境中执行,会创建变量对象的一个作用域链

    • 作用域链的用途是保证所有变量和函数的有序访问

    • 作用域链的前端始终是当前执行的代码所在环境的变量对象

    • 如果环境是函数,将其活动对象作为变量对象,arguments作为第一个变量(全局环境不存在arguments)

    • 全局执行环境的变量对象始终是作用域链最后的一个对象

      const color = 'blue';
      
      function changeColor() {
          const anotherColor = 'red';
      
          function swapColors() {
              const tempColor = anotherColor;//red
              anotherColor = color;//blue
              color = tempColor;//red
          }
      
          swapColors();
      }
      
      changeColor();复制代码

作用域.png

  • 内部环境可以通过作用域访问所有外部环境

  • 外部环境不能访问内部环境是变量和函数

  • 环境可以向上搜索作用域链,查询变量,和函数, 不可以向下收索进入内部环境

  • 延长作用域链,临时,添加一个变量对象到作用域链的前端

    • try-catch 中的catch

    • with语句

没有块级作用域

  • var声明的变量,会添加到最接近的环境中,函数内部,最接近的环境就是函数的局部环境

if(true){
    var c='blue'
}
console.log(c)//blue
for(var i=0;i<10;i++){
    doSomething(i)
}
console.log(i);//10复制代码

JavaScript自动回收垃圾

垃圾收集方式

  • mark-and-sweep(标记清除)

    • 进入环境进行标记

    • 离开环境进行标记

    • 存储在内存中的所有变量加上标记

    • 先清除标记,之后再加标记就是准备删除,最后垃圾收集器完成内存清除工作

  • 引用计数

    • 引用一次,次数加1

    • 当引用为0,进行内存回收


作者:LanceZhang
链接:https://juejin.cn/post/7036708981183610910

 伪原创工具 SEO网站优化  https://www.237it.com/ 


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐