原始类型和引用类型
JavaScript中是不允许直接修改内存中的数据,只能操作这个对象的引用
注意:JavaScript中字符串类型与其他语音不同,JavaScript的字符串类型是基本数据类型,不是引用类型。
深复制和浅复制
基本数据类型的六种是把值复制到栈的新的内存空间中,深复制
引用数据类型,修改指针的指向,堆中不会复制一份新的变量,浅复制
基本实现
上下文和作用域
一段上下文在执行完所有的代码之后,这个上下文就会被销毁。
全局上下文是最外层的上下文,在浏览器中全局上下文窗口对象(window)
全局创建的方法和变量,都是window对象的属性和方法。
使用let和const在最上层进行定义,不会算在全局的上下文里,但是可以被解析到作用域链中。
注意:全局上下文,在整个应用退出之前都不会销毁
方法的上下文
方法有自己的上下文,和属性不一样,方法是在上下文栈中,不管是否执行到该方法,先都压入栈中,执行完一个方法,从栈中弹出一个方法。
上下文链结构图
一个内层的上下文可以通过外层上下文链访问所有东西,但外层上下文并不能通过一个内层的上下文访问所有东西。
方法作用域内使用var定义变量
在方法作用域内,使用var定义变量,会自动添加到可用的最直接的上下文。在方法中,最直接的上下文之一是with语句。如果变量被初始化没有被声明则会自动添加到全局上下文中。
举例:
这么写就会报错
function addSum(num1, num2) {
var sum = num1 + num2
return sum
}
let result = addSum(1,2)
console.log(sum)
这样写就不会报错
function addSum1(num1, num2) {
sum = num1 + num2
return sum
}
let result1 = addSum1(1,2)
console.log(sum)
垃圾回收
JavaScript是垃圾回收机制语言,意味着执行环境需要管理代码执行期间的内存空间(不需要开发者手动管理)。
一般情况下生命周期内方法内部的局部变量,在离开作用域通常就认为不再使用了,但也有不平常的情况,就需要两种技术对特殊情况的处理,标记-清除和引用计数。
标记-清除
一个变量进入了上下文,会被标记在上下文中,这块内存将不会被释放。
变量离开上下文,会被标记在上下文外。
当垃圾回收器运行,会清除内存中标记在上下文中的变量,和被变量引用的在上下文中的变量,清除标记值并且回收对应的内存空间。
引用计数
和iOS一样,定义时引用计数为0,该变量多一个引用加1,少一个减1,为0时释放(不过iOS的引用计数是对于对象来说,这本书里说的是变量,不知道是我英语水平问题,还是这边就这样)
使用let和const提升性能
let和const是块级作用域,var可能会出现定义提升的问题,作用域不稳定,let和const可以尽快被进行垃圾回收,提升性能
隐藏类和删除操作
V8引擎会隐藏类,V8引擎会把两个相同类的实例共享一个隐藏类,这样可以共享构造函数和原型,提高性能