| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> JavaScript知识库 -> 【JS高程设计学习笔记】第4章-变量、作用域与内存 -> 正文阅读 |
|
[JavaScript知识库]【JS高程设计学习笔记】第4章-变量、作用域与内存 |
4.1 原始值与引用值ES变量包括两种不同类型的数据,原始值(primitive value)和引用值(reference value)则是由多个值构成的对象。 六种原始值:Undefined,Null,Boolean,Number,String,和Symbol 保存原始值的变量是按值(by value)访问的,因为我们操作的就是存储在变量中的实际值 引用值是保存在我们内存中的对象,JavaScript不允许直接访问内存,所以不能直接操作对象所在的内存空间。因此保存引用值的变量是按引用( by reference)访问的。 动态属性 对于引用值而言,可以随时添加,修改,和删除其属性和方法。 原始值不能有属性,尽管给原始值添加了属性也不会报错。 但原始类型初始化是,用的是new()关键字,则js会创造一个Object实例,如下
复制值 除了存储方式不同,原始值和引用值通过变量复制时也不同。比如: let num1 = 5; let num2 = num1; 这两个变量可以独立使用,互不干扰; 但是如果把引用值从一个变量赋值给另一个变量时,这里复制的实际上是一个指针,它指向存储在堆内存中的对象。操作完成后,两个变量实际上指向同一个对象,因此一个对象上面的变化,会在另一个对象上反映出来。 传递参数 ES中所有参数都是按值传递的,不管是原始类型还是引用类型。 ES中的函数的参数就是局部变量 确定类型 typeof可以用来确定原始值的类型 但是对于引用值,通常不关心一个值是不是对象,而是想知道它是什么类型的变量,可以用用instanceof操作符。如果变量是给定引用类型(由原型链决定)的实例,则instanceof操作符返回true。 4.2 执行上下文与作用域变量或函数的上下文决定了它们可以访问哪些数据。每个上下文都有一个关联的变量对象,而这个上下文中定义的所有变量和函数都存在于这个对象上。但我们无法通过代码访问到变量对象。 上下文中的代码在执行的时候,会创建变量对象的一个作用域链(scope chain)。全局上下文的变量对象始终是作用域链的最后一个变量对象。 内部上下文可以通过作用域链访问外部上下文的一切,但外部上下文无法访问内部上下文中的任何东西。 函数参数被认为是当前上下文中的变量。 作用域链增强 某些语句会导致在作用域链前端临时添加一个变量对象,这个上下文在代码执行后会被删除。通常有两种情况: try/catch with语句 变量声明 var函数作用域声明: let块级作用域声明:let存在暂时性死区,在提升变量上和var不同 const的常量声明:必须初始化,在生命周期内的任何时候都不能重新赋值 在严格模式下,未经声明就初始化变量会报错 标识符查找:查找标识符时会先搜索作用域链前端,若没找到,则沿着作用域链搜索,一直持续到搜索至全局上下文的变量对象,如果仍然没找到,则说明其未声明。 标识符查找并非没有代价,局部变量访问要比全局变量访问快。 4.3 垃圾回收JS是使用垃圾回收的语言,基本思路很简单:确定哪个变量不会再使用之后,就会释放它的内存,这个过程是周期性的。 标记清理 最常用的垃圾回收策略就是标记清理(mark-and-sweep)。当变量进入上下文,比如在函数内部声明一个变量时,这个变量会被加上存在于上下文的标记。当变量离开上下文时,也会被加上离开上下文的标记。 垃圾回收程序在运行的时候,会标记内存中存储的所有变量。然后它会将所有在上下文的变量,以及被在上下文中的变量引用的变量的标记去掉。其余的被标记的变量就是待删除的。随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回他们的内存。 引用计数 另一种没那么常用的垃圾回收策略就是引用计数(reference counting)。思路是对每个值都记录它被引用的次数。如果引用数为0,则会被垃圾回收程序回收。 引用计数最大的问题:循环引用的问题,导致大量内存无法被释放 性能 垃圾回收程序会周期性运行,如果内存中分配了很多变量,则可能造成性能损失,因此垃圾回收的时间调度很重要。 垃圾回收有可能会明显拖慢渲染的速度和帧速率,最好是无论什么时候开始收集垃圾,都能让它们尽快结束工作。 现代垃圾回收程序会基于js的运行环境的探测来决定何时执行,比如根据已分配对象的大小和数量来判断。 IE7对JS引擎的垃圾回收程序修改之后,编程动态改变分配变量等会出发垃圾回收的阀值。如果有一次回收的内存达到了已分配内存的85%,则阀值设为默认值。大大提升了重度依赖js的在web中的性能 内存管理 优化内存占用的最佳手段就是保证在执行代码时只保存必要的数据。如果数据不再必要,那么把它设置为null,这也可以叫做解除引用。 通过const和let声明提升性能:使用这两个关键字,可能让垃圾回收程序更快介入 隐藏类和删除操作:Chrome V8引擎在将解释后的JS代码编译为实际的机器码时会利用隐藏类,如果代码非常注重性能,则这个很重要。最佳实践是,把不想要的属性设置为null,这样可以保持隐藏类不变和继续共享,同时也能达到删除引用值供垃圾回收程序回收的效果。 内存泄漏:意外声明全局变量是最常见但最容易修复的内存泄漏问题。只需要在前面加上var,let,const即可。其次,定时器也可能造成内存泄漏,闭包也很容易在不知不觉间造成内存泄漏。 静态分配与对象池:压榨浏览器,如何减少浏览器执行垃圾回收的次数就是需要考虑的。浏览器决定何时运行垃圾回收程序的一个标准就是对象更替的速度。假设有一个计算二维矢量加法的函数,很影响性能,那么解决方案是不要动态创建矢量。另一个策略就是使用对象池。在初始化的某一时刻,可以创建一个对象池,用来管理一组可回收的对象。静态分配(对象池只按需分配)实际上是优化的一种极端形式,大多数情况属于过早优化,不用考虑。 总结
|
|
JavaScript知识库 最新文章 |
ES6的相关知识点 |
react 函数式组件 & react其他一些总结 |
Vue基础超详细 |
前端JS也可以连点成线(Vue中运用 AntVG6) |
Vue事件处理的基本使用 |
Vue后台项目的记录 (一) |
前后端分离vue跨域,devServer配置proxy代理 |
TypeScript |
初识vuex |
vue项目安装包指令收集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 16:42:09- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |