ECMAScript变量可以包含两种不同类型的数据:原始值和引用值原生值和引用值的区别什么是原始值:最简单的值例如:Undefined、Null、Boolean、Number、String、Symbol、BigInt。保存原始值的变量是按值访问的,因为我们操作的是变量中存储的实际值什么是引用值:由多个值组成的对象例如:Object.引用值是存储在内存中的对象,存储引用值的变量是通过引用来访问的。由于JavaScript不允许直接访问内存位置,因此它实际上操作对象的引用而不是对象本身。区别:动态属性:原始值:无属性引用值:可以随时添加、修改、删除其属性和方法复制值:原始值:复制值变量可以独立使用,互不干扰。letnum=123;letnum1=num;console.log(num,num1)//123,123num=100;console.log(num,num1)//100,123参考值:复制值,复制栈中的指针(对象在堆中的地址),指向同一个对象letobj={name:"lly",sex:"Man"}letobj1=obj;console.log(obj,obj1)//{name:"lly",sex:"Man"},{name:"lly",sex:"Man"}obj.age=20console.log(obj,obj1)//{name:"lly",sex:"Man",age:20},{name:"lly",sex:"Man",age:20}传参:原值:同原值变量的副本functionadd(num){num+=10;返回数;}让计数=20;让结果=添加(计数);控制台日志(计数);//20,没有变化console.log(result);//30参考值:与参考值变量的副本相同functionsetName(obj){obj.name="lly";}让person=newObject();设置名称(人);控制台日志(人名);//"lly"判断类型的方法:原始类型值:typeof引用类型值:instanceof更全面的判断方法:Object.prototype.toString.call(类型值待判断);执行上下文和作用域什么是执行上下文:当前JavaScript代码解析执行环境的抽象概念执行上下文类型1.全局执行上下文3.函数上下执行Text2.Block-levelexecutioncontext什么是作用域:一个独立的区域,不允许变量泄露和暴露。简单的说就是隔离变量的空间。特点:同名变量在不同作用域内不会相互冲突。作用域类型:全局操作域函数作用域块级作用域变量声明类型及特点只是临时死区造成的,在变量声明之前是不可用的,不能在同一个作用域内声明两次。const常量声明必须同时初始化值。一旦声明,不能再赋值(初始值为原值,不能再赋值。赋给其他引用,引用的值没有限制),其他特性同let。垃圾收集机制JavaScript是一种使用垃圾收集的语言。执行环境负责在代码执行时管理内存。通过自动内存管理实现内存分配和闲置资源回收。实现思路:确定变量未被使用后,释放占用的内存。垃圾回收的标记策略主要采用:标记清理和引用计数。标记清理原理离开范围的值会自动标记为可回收,然后在垃圾回收时删除,先标记当前未使用的值,再回来回收它们的内存引用计数原理(不常用)记录每个值的引用数。当引用数为0时,垃圾回收器会在下次运行时释放引用数为0的值的内存。引用数的规则:当声明一个变量并为其赋一个引用值时,该值的引用计数为1。如果将相同的值赋给另一个变量,则引用计数加1。同理,如果该变量持有这个值的引用被其他值覆盖,那么引用的数量将减少1。性能垃圾收集器将定期运行。频繁调度的垃圾收集器会严重影响性能,因此浏览器使用了很多性能优化方案:1.分代收集:对象分为“新”和“旧”两组。许多对象出现、完成它们的工作并很快消亡,它们可以很快被清理掉。那些存活时间长的对象会变“老”,被检查的频率降低2.增量收集:如果对象很多,我们试图一次遍历并标记整个对象集,这可能需要一些时间,并引入明显的延迟在执行期间。所以引擎试图将垃圾收集工作分成几个部分。然后将这些零件一一加工。这将需要在它们之间添加额外的标记来跟踪变化,但这将有许多微小的延迟而不是一个大的延迟。3.空闲时间收集:垃圾收集器只会在CPU空闲时尝试运行,以减少可能对代码执行造成的影响。内存管理1.通过const和let声明提高性能:由于const和let的作用域是块而不是函数,垃圾回收器可以更早介入,尽快回收该回收的内存。这改进了垃圾收集过程。2、隐藏类和删除操作:隐藏类:JavaScript引擎引入隐藏类来提高性能。在运行过程中,V8会将创建的对象与隐藏类相关联,以跟踪它们的属性特征。functionpeople(){this.name='lly';}让a1=新人();让a2=新人();a2.sex="Man"解决方法是避免JavaScript“先创建后补充”的风格,在构造函数中一次声明所有属性。functionpeople(sex){this.name='lly';this.sex=sex}leta1=newpeople();leta2=newpeople("Man");删除操作:使用delete关键字结果相同最佳做法是将不需要的属性设置为null。functionpeople(){this.name='lly';this.sex="Man"}leta1=newpeople();让a2=新人();deletea1.sex;//不推荐a1.sex=null//最佳实践3、内存泄漏的原因及解决方法:关闭:手动设置null,切断对非预期全局变量的引用:使用严格模式或在中添加声明关键字frontofitTimer:当需要定时器的时候不要清除定时器4.静态分配和对象池:对象池:一种JavaScript优化策略,用来管理一组可回收的对象。应用程序可以从这个对象池中请求一个对象,设置它的属性,使用它,然后在操作完成后将它返回到对象池中。由于对象初始化不会发生,垃圾收集探测器不会检测到对象替换,因此垃圾收集器不会经常运行静态分配:一种极端的优化形式。如果您的应用程序受到垃圾收集的严重阻碍,可以使用它来提高性能。但这种情况很少见。在大多数情况下,这是过早的优化,所以不用担心。
