• JS变量、作用域和内存问题


    基础知识

    • 5种基本数据类型:Undefined、Null、Boolean、Number、String
    • 基本类型值指的是那些保存在栈内存中的简单数据段、引用类型值则是指那些保存在堆内存中的对象
    • ECMAScript中所有函数参数都是按值传递的。(按值传递和按引用传递)。在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量(形参),因此局部变量的变化会反映在函数的外部
      //传递参数(值传递)
          //1、向参数传递基本类型的值时
          function addTen(num) {
              num += 10;
              return num;
          }
          var count = 20;
          var result = addTen(count);
          debug(count);            //20
          debug(result);            //30
          //2、向参数传递引用类型的值时
          function setName(obj) {
              //此处值传递,obj与person引用的是同一个对象
              //等价于person把对象的地址传递给了obj(与引用传递不同:别名)
              obj.name = 'mackcu';
          }
          var person = new Object();
          setName(person);
          debug(person.name);        //mackxu
          //证明不是引用传递的实例
          function setName(obj) {
              obj.name = 'mackxu';
              obj = new Object();
              obj.name = 'zhangsan';
          }
          var person = new Object();
          setName(person);
          debug(person.name);        //mackxu
    • 检测类型(根据规定,所有的引用类型的值都是Object的实例)。检测基本类型值时用typeof,检测引用类型值时用instanceof操作符
      //类型检测
          var s = 'mackxu';
          var b = true;
          var i = 22;
          var u;
          var n = null;
          var o = new Object();
          //["string", "boolean", "number", "undefined", "object", "object", 'function']
          var type = [typeof s, typeof b, typeof i, typeof u, typeof n, typeof o, typeof setName];

    执行环境及作用域

    执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为

    每一个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中

    例如:全局执行环境与之关联的对象是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的

    每一个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境会被推入一个环境栈中,而在函数执行之后,栈将其环境栈弹出,把控制权返回给之前的执行环境.这就是ECMAScript执行流的工作原理

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

        作用域链的作用:保证对执行环境有权访问的所有变量和函数进行有序访问(向上搜索作用域链)

    没有块级作用域

    //没有块级作用域    声明变量
        if (true)
        {
            var color = 'red';
        }
        debug(color);        //red
        for (var i=0; i<10 ; i++ );
        debug(i);            //10
        //声明变量:
        //在使用var关键字声明时,这个变量将自动添加到距离最近的可用环境中。如果赋值给未声明的变量,该变量将添加到全局环境中
        function add() {
            //如果赋值的变量还未声明,该变量会自动声明[隐式声明为全局变量]。
            sum = 10+10;
        }
        add();
        debug(sum);        //20

    垃圾回收:标记清除

    工作原理:垃圾收集器在运行时会给存储在内存中的所有变量都加上标记。然后会去掉当前环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备清除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾收集器完成内存清除工作,销毁那些带有标记的值并回收它们所占用的内存空间

    摘自:JavaScript高级程序设计(第2版)

  • 相关阅读:
    数论分块与整除相
    P3254——DP&&入门
    P3384——树链剖分&&模板
    树链剖分模板
    P4145——线段树点修改&&模板题
    P1198最大数——线段树点修改&&模板题
    线段树(四)——两个标记(add和set)
    epoll 知识总结
    C++中的mutable关键字
    [LeetCode] Max Points on a Line
  • 原文地址:https://www.cnblogs.com/mackxu/p/2775832.html
Copyright © 2020-2023  润新知