基本类型和引用类型的值
基本类型的值是按值访问的,修改变量时直接对值进行操作。引用类型的值是通过引用访问的,不能直接操作内存中的值。
基本类型与引用类型的差异:
- 引用类型可以动态的添加属性;
var obj=new Object()
obj.name='marry'
console.log(obj.name)//marry
- 基本类型的复制是为将值复制一份存放到新的变量中,两个变量的值是相互独立的。引用类型的复制是将指向值的引用复制到新的变量中,一旦其中一个变量修改了值,另一变量的值也会同时修改;
var num1=5
var num2=num1
console.log(num2) //5
console.log(num1) //5
num2=4
console.log(num2) //4
console.log(num1) //5
var obj1={name:'marry',age:14}
var obj2=obj1
console.log(obj1) //{name: "marry", age: 14}
console.log(obj2) //{name: "marry", age: 14}
obj2.age=20
console.log(obj1) //{name: "marry", age: 20}
console.log(obj2) //{name: "marry", age: 20}
- 在参数传递时,基本类型和引用类型都是按值传递,引用类型的传参是将值在内存中的地址复制给局部变量;
- typeof操作符可以用来检测基本数据类型,instanceof操作符用于检测引用类型。
var obj=new Object()
console.log(obj instanceof Object) //true
执行环境及作用域
执行环境
执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有变量对象,其中存放着环境中定义的所有变量和函数。
js中每一个函数都有自己的执行环境,还有一个全局的执行环境。在执行一个函数时,函数的环境会被推入一个环境栈中,函数执行之后,将函数执行环境弹出栈,将控制权交给之前的执行环境。
作用域链
执行函数时,函数会创建变量对象的作用域链。作用域链将相关联的执行环境链接在一起。作用域的前端是当前代码的执行环境,后端为下一个变量对象的包含环境,而下一个变量对象则来自下一个包含函数,直到全局执行环境。
作用域链的作用是有序访问执行环境的所有变量和函数。
标识符的查找从作用域链的前端开始搜索,直至最后的全局作用域。遇到匹配的标识符,就会停止搜索。
作用域
ES5中没有块级作用域,只有函数作用域和全局作用域。
for(var i=0;i<10;i++){
}
console.log(i) //10
若存在块级作用域,在执行完循环后在循环外应该无法访问i的值。
垃圾收集
js中有自动清除内存的策略,js会在一定时间间隔内进行垃圾的自动收集,通过判断哪个变量有用哪个变量没有,为没有的变量打上标记,清除带标记的变量。一般有两种清除策略:
- 标记清除
垃圾收集器会给所有在内存中的变量加上标记,然后去掉环境中的变量以及被环境中变量引用的变量的标记。在这之后被添加标记的变量表示要删除的变量。 - 引用计数
跟踪记录每个值被引用的次数。当声明一个变量并将引用类型的值赋给该变量时,则这个值的引用次数为1,如果同一个值又被赋给另一个变量,则该值的引用次数加1。若包含这个值引用的变量又取得另一个值,则该值的次数减1。当引用次数为0时,就会回收该值。引用计数的问题时对于循环引用的数据不会被回收,解决方法需要手动切断循环引用的联系。