操作:从一个变量向另一个变量复制基本类型和引用类型
基本类型的值,保存的是变量的副本,两个变量完全独立,改变其中一个,不会影响另一个 var num1=5; var num2=num1; var num2=6; //互不影响 console.log(num1);//5 console.log(num2);//6 引用类型的值,保存的是对象指针的副本,改变其中一个,会影响另一个 var obj1=new Object(); var obj2=obj1; //有影响 obj1.name="tom"; console.log(obj2.name);//"tom"按值传递
值”的含义: 这里的值,指的是,复制传进来的对象的地址,把这个复制值赋给参数
引用传递的含义: 直接将变量本身的地址传进去,直接把传进来的对象的地址传给参数
参数传递的过程:
把传进来的对象的地址复制一份把这个复制出来的值传给参数参数和传进来的对象访问的是一个地址,对参数进行操作会表现在对象上结合代码进行理解:
function setName(obj) { obj.name = 'XX'; // 对obj进行操作会表现在person上 obj = new Object(); // 这里obj的引用改变了,如果传递的是引用,那么person的地址也会改变,也就是说,接下来对obj的操作,也会表现在person上 obj.name = 'YY'; } let person = new Object(); setName(person);示例:
var color=“bule”; function changeColor(){ var anotherColor=“red”; function swapColors(){ var tempColor=anotherColor; anotherColor=color; color=tempcolor; //这里可以访问color,anotherColor和tempColor } 这里可以访问color,anotherColor,但不能访问tempColor swapColor(); } //这里只能访问color changeColor()分析执行环境
window colorchangeColor anotherColorswapColors tempColor 内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量核函数这些环境都是线性的,有次序的,每个环境都可以向上搜索作用域链,查询变量和函数;但任何环境不能通过向下搜索作用域链而进入另一个执行环境。示例
var color=“bule”; function getColor(){ return color; } console.log(getcolor());//"bule"查询过程
搜索getColor,查找color,没有继续向上搜索搜索全局对象,查找到color,所以搜索结束。定义
当变量进入环境时,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到他们。当变量离开环境时,则将其标记为“离开环境”。
标记清除算法分为标记和清除两个阶段.这个算法假定设置一个叫做根(root)的对象(在 Javascript 里,根是全局对象).垃圾回收器将定期从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象,然后对这些对象进行标记……从根开始,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象.之后进入了清除阶段,标记的对象会与内存中的对象进行比较,然后清除内存中那些没有标记的对象
标记阶段,它将遍历堆中所有对象,并对存活的对象进行标记;清除阶段,对未标记对象的空间进行回收.定义
跟踪记录每个值被引用的次数,当声明了一个变量并将一个引用类型赋给该变量时,则这个值的引用次数就是1.如果同一个值又被赋给另一个变量则该值的引用次数加1.相反这个值的引用的变量又取得另一个值.则这个值的引用次数减1.
最大的问题:循环引用是对象A中包含一个指向对象B的指针而对象B中包含一个指向对象A的引用 function f(){ var o = {}; var o2 = {}; o.a = o2; // o 引用 o2 o2.a = o; // o2 引用 o return "azerty"; } f();