JavaScript高级程序设计(第4版)学习随笔【第四章】

来了来了 第四章来了 这章节主讲变量、作用域与内存
不同与typeScript的严格要求,JavaScript的变量是松散类型的,这样的变量可以存放数值也可以存放字符串以及对象数组等等,听起来很强大吧,但也容易引出一些问题。

  • 原始值与引用值

    • 原始值就是最简单的数据,引用值则是由多个值构成的对象。
      保存原始值的变量是按值(by value)访问的,因为我们操作的就是存储在变量中的实际值。引用值是保存在内存中的对象.
    • 原始值不能有属性。
      在这里插入图片描述
      在这里插入图片描述
      但用new关键词声明的话,就会创建一个object类型的实例。
      在这里插入图片描述
    • 复制值
      在把原始值或引用值从一个变量赋给另一个变量时,存储在变量中的值都会被复制到新变量所在的位置。区别在于,引用值复制的值实际上是一个指针,它指向存储在堆内存中的对象。操作完成后,两个变量实际上指向同一个对象。
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述在这里插入图片描述
      这里就需要了解到如何复制一个对象,也能像原始值一样,可以独立不影响被复制的对象,那就是我们常说的深拷贝
      在这里插入图片描述
      深拷贝的方法很多,JSON深拷贝只能用于较为简单的对象,当含有函数,层级复杂等等就不适用了。
      学完这期,我会出一篇专门如何进行深拷贝,以及各个方法的优缺点的文章(网上也有很多总结完善的文章),我自己梳理一遍,会更加印象深刻一些。
      (呐呐呐,2021/10/25补充来了。浅拷贝和深拷贝篇
      好了继续。
    • 传递参数
      ECMAScript中所有函数的参数都是按值传递的。函数外的值传到函数内部,就像一个变量复制到另一个变量,所以和复制值一样。在这里插入图片描述
      在这里插入图片描述
    • 确定类型
      前一章提到的typeof操作符,它是判断一个变量是否为字符串、数值、布尔值或undefined的最好方式。
      typeof仅适用于判断原始值,对引用值用处不大。
      为了解决这个问题,ECMAScript提供了instanceof操作符,会返回true或false.
      在这里插入图片描述
      看到这是不是又产生一个疑问:为什么b又是数组又是对象的呢?
      因为按照定义,所有引用值都是Object的实例,因此通过instanceof操作符检测任何引用值是否为object都会返回true。
  • 执行上下文与作用域
    变量或函数的执行上下文(简称上下文)决定了它们可以访问哪些数据,以及它们的行为。每个上下文都有一个关联的变量对象(variable object),而这个上下文中定义的所有变量和函数都存在于这个对象上。
    上下文中的代码在执行的时候,会创建变量对象的一个作用域链(scope chain)。这个作用域链决定了各级上下文中的代码在访问变量和函数时的顺序。
    上下文在其所有代码都执行完毕后会被销毁,包括定义在它上面的所有变量和函数(全局上下文在应用程序退出前才会被销毁,比如关闭网页或退出浏览器)。

    • 作用域链增强
      虽然执行上下文主要有全局上下文和函数上下文两种(eval()调用存在第三种上下文),但有其他方式来增强作用域链。比如try/catch的catch块,之前说到的with语句,都会在作用域链前端添加一个变量对象。
    • 变量声明(es6前仅有var唯一一个关键词声明变量,es6后增加了let const 上章有讲到)
    • 标识符查找
      搜索开始于作用域链前端,找到即停止搜索,找不到就往外沿着作用域链继续搜索持续到搜索至全局上下文的变量对象,若还是未找到,则说明其未声明。
      在这里插入图片描述
      调用aFun()函数会引用变量a,为了确定a的值就会在函数内部找,没找到,往外找找到了全局变量a的值 于是返回“全局变量”
      访问局部变量比访问全局变量要快,因为不用切换作用域。
    • 垃圾回收
      JavaScript是使用垃圾回收的语言,也就是说执行环境负责在代码执行时管理内存。通过自动(周期性的)内存管理实现内存分配和闲置资源回收,基本思路很简单:确定哪个变量不会再使用,然后释放它占用的内存。
      垃圾回收过程是一个近似且不完美的方案,因为某块内存是否还有用,属于“不可判定的”问题,靠算法是解决不了的。
      那么,如何标记未使用的变量呢,在浏览器的发展史上,用到过两种主要的标记策略:标记清理和引用计数
    • 标记清理
      js最常用的垃圾回收策略是标记清理,垃圾回收程序运行的时候,会标记内存中存储的所有变量(标记的方法很多),它会将所有在上下文中的变量,以及被在上下文中的变量引用的变量的标记去掉。在此之后再被加上标记的变量就是待删除的了,原因是任何在上下文中的变量都访问不到它们了,随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回它们的内存。
      到了2008年,IE、Firefox、Opera、Chrome和Safari都在自己的JavaScript实现中采用标记清理(或其变体),只是在运行垃圾回收的频率上有所差异。
    • 引用计数
      另一种没那么常用的垃圾回收策略是引用计数。对每个值都记录他被引用的次数,被引用数+1,引用该值的标量被其他值覆盖了,引用数-1,当一个值引用数为0时,垃圾回收程序运行时就会将它占的内存释放。
      很引用计数并不适用循环引用场景,因为循环引用下,它们的引用数永远不会变成0,多次调用后大量内存不会被释放,因此Netscape在4.0版放弃了引用计数,转而采用标记清理。事实上,引用计数策略的问题还不止于此。
    • 性能
      垃圾回收程序是周期性运行的,如果内存中分配了很多的变量,可能回造成性能损失,所以垃圾回收的时间调度很重要,因此最好的办法是在写代码时就要做到:无论什么时候开始收集垃圾,都能让它尽快结束工作。
      警告 在某些浏览器中是有可能(但不推荐)主动触发垃圾回收的。在IE中,window. CollectGarbage()方法会立即触发垃圾回收。在Opera 7及更高版本中,调用window. opera.collect()也会启动垃圾回收程序。
    • 内存管理
      JavaScript运行在一个内存管理与垃圾回收都很特殊的环境。分配给浏览器的内存小得多,所以开发者需要考虑将内存尽可能减少,让页面性能更好。优化内存占用的方法有很多种:
      • 解除引用
        数据不再需要时将其置为null,解除引用,下一次垃圾回收程序运行时就会将它的内存收回。
      • 通过const和let声明提升性能
        块作用域比函数作用域能更早被回收。
      • 隐藏类和删除操作
        截至2017年,Chrome是最流行的浏览器,使用V8 JavaScript引擎,运行期间,V8会将创建的对象与隐藏类关联起来,以跟踪它们的属性特征。能够共享相同隐藏类的对象性能会更好。
      • 内存泄漏
        不规范声明全局变量、不规范引用定时器都可能导致内存泄漏。
      • 静态分配与对象池
        提升JavaScript性能,压榨浏览器,关键问题就是如何减少浏览器执行垃圾回收的次数。
        尽量不要动态创建矢量对象。
      • 注意 静态分配是优化的一种极端形式。如果你的应用程序被垃圾回收严重地拖了后腿,可以利用它提升性能。但这种情况并不多见。大多数情况下,这都属于过早优化,因此不用考虑。
  • 小结

    • JavaScript变量可以保存两种类型的值:原始值和引用值。
    • 原始值大小固定,因此保存在栈内存上
    • 引用值是对象,存储在堆内存上。
    • 执行上下文分全局上下文、函数上下文和块级上下文
    • 解除变量的引用不仅可以消除循环引用,而且对垃圾回收也有帮助,全局对象、全局对象的属性和循环引用都应该在不需要时解除引用。
### 回答1: 《JavaScript高级程序设计》第4是一本深入讲解JavaScript编程语言的书籍。该书详细介绍了JavaScript的基础知识、语法、面向对象编程、DOM操作、事件处理、Ajax、JSON等方面的内容。此外,该书还介绍了一些高级技术,如模块化编程、正则表达式、Web Workers、Web Storage等。该书适合有一定JavaScript基础的读者阅读,可以帮助读者深入了解JavaScript编程语言,提高编程技能。 ### 回答2: 《JavaScript高级程序设计》第4(以下简称《JS高级程序设计》)是由李炎恢编写的一部JavaScript语言的经典教材,它被誉为“JavaScript圣经”。本书全面深入地讲解了JavaScript语言的核心概念、高级特性和最佳实践,对于想要深入学习JavaScript的开发者来说是一本必读之作。 首先,本书从JavaScript的基础知识开始,包括JavaScript的数据类型、变量、运算符、函数等。随后,本书详细介绍了JavaScript的面向对象编程,包括对象、原型、继承等概念,以及使用构造函数和类来创建对象的方法。 其次,本书不仅讲述了JavaScript的基本语法,更详细深入地介绍了诸如函数表达式、闭包、高阶函数、递归等高级特性,对于想要提高自己的JavaScript编程能力的开发者很有帮助。 最后,本书也介绍了一些实际的开发技巧和最佳实践,例如DOM操作、事件处理、Ajax、JSON、模块化开发等,让开发者在实际的开发中更加得心应手。 总之,《JavaScript高级程序设计》第4是一本权威性的JavaScript经典教材,它涵盖了JavaScript的核心概念、高级特性和最佳实践,对于想要深入了解JavaScript的开发者来说是一本必读之作。无论是初学者还是有经验的开发者,都可以从中找到大量有用的知识和实践经验。 ### 回答3: 《JavaScript高级程序设计》第4是由三位著名的前端开发专家编写的JavaScript权威教程。本书介绍了JavaScript的核心概念、语言特性和应用方法,以及一些高级技巧和最佳实践。 本书的第一部分从JavaScript基础语法开始介绍,包括变量声明、数据类型、操作符、语句和函数等方面。第二部分主要介绍JavaScript的面向对象编程,包括原型链、继承和封装等概念。第三部分主要介绍JavaScript的一些高级特性,包括闭包、异步编程、事件和延迟加载等内容。第四部分主要介绍了如何使用JavaScript实现一些实际应用,包括调试、性能优化、动态Web页面和跨域请求等方面。 本书内容全面、深入,不仅介绍了JavaScript的基础知识,更重要的是让读者理解了JavaScript的思想和编程风格。编写本书的三位专家都是行业内的大牛,他们的经验和见解非常宝贵,能够帮助读者更好地理解JavaScript。同时,本书的配套网站还提供了很多实例代码和练习题,读者可以通过这些实践来深入理解JavaScript。 总之,《JavaScript高级程序设计》第4是一本非常不错的JavaScript权威教程,无论是初学者还是专业开发者都可以从中受益匪浅。如果你想深入学习JavaScript,这本书绝对值得一读。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值