文章目录

1. JavaScript 中的垃圾回收机制(GC)

1.1 垃圾回收相关概念

① 什么是垃圾

1. 用不到的数据,就是垃圾
2. JavaScript 中没有被引用的对象,就是垃圾对象

② 什么是垃圾回收

1. 销毁垃圾对象,释放内存,就是垃圾回收
2. 需要手动垃圾回收的编程语言: C、C++
3. 自动垃圾回收的编程语言: Java、Python、JS 等

③ 垃圾没有及时回收的后果

垃圾没有及时回收造成内存泄漏,越来越多的内存泄漏会导致内存溢出

内存溢出: 需要使用内存的时候,内存空间不够。

内存泄漏: 垃圾没有回收称为内存泄漏。

④ JavaScript 垃圾回收的常见算法

- 引用计数
- 标记清除

1.2 引用计数

① 原理

- ① 对象有个引用标记
- ② 如果对对象进行了引用 +1
- ③ 取消了对象对象的引用 -1
- ④ 当引用标记=0的时候,变为垃圾对象,并删除

② 优缺点:

- 优点: 及时清除垃圾对象
- 缺点: 互相引用的对象导致无法被回收(内存泄漏)

1.3 标记清除

① 原理

浏览器不停地进行标记清除,每一轮分为标记和清除两个阶段
- 标记阶段:从根对象出发,每一个可以从根对象访问到的对象都会被添加一个标记,于是这个对象就被标识为可到达对象。
- 清除阶段:垃圾回收器,会对内存从头到尾进行线性遍历,如果发现有对象没有被标记为可到达对象,那么就将此对象占用的内存回收。
该轮结束,将原来标记为清除,以便进行下一轮标记清除。

② 优缺点

- 优点:  不会内存泄漏
- 缺点: 需要深度递归,耗费资源较多

2 执行上下文和执行栈

2.1 执行上下文

① 全局执行上下文

1. 打开页面,js代码执行之前,创建 window 对象,确定 window 就是全局执行上下文对象
2. 对全局执行上下文对象进行预处理
① 找到使用 var 的变量声明语句,给全局执行上下文对象添加属性,但不赋值
② 找到使用 function 的函数声明语句,给全局执行上下文对象添加属性,值是函数
③ 给 this 进行赋值,将全局执行上下文对象赋值给 this
3. 正式执行全局代码
4. 页面关闭,全局执行上下文对象销毁

② 函数内的执行上下文

1. 调用函数的时候,函数内代码执行之前,创建该函数的执行上下文对象;
2. 对函数内执行上下文对象进行预处理
① 将形参作为函数内执行上下文对象的属性,并赋值
② 给函数内执行上下文对象添加属性arguments,并赋值
③ 找到函数内使用 var 的变量声明语句,给函数内执行上下文对象添加属性,不赋值
④ 找到函数内使用 function 的函数声明语句,给函数内执行上下文对象添加属性,值是函数
④ 给 this 进行赋值,将调用该函数的对象赋值给 this
3. 正式执行函数内的语句
4. 函数调用结束,函数内执行上下文对象被销毁

注意: 函数每调用一次,就创建一个执行上下文对象。

2.2 执行栈

栈结构: 是一种数据存储结构,特点先进后出,后进先出。

**执行
栈:**执行上下文对象创建之后,要放入执行栈,放入执行栈才能执行。

2.3 作用域和执行上下文的关系

区别:

1. 变量的作用域在函数声明的时候就确定了,是静态的
2. 执行上下文对象函数调用的时候才创建,每调用一次就创建一次,调用结束会销毁,是动态的

联系:

执行上下文对象从属于所在的作用域:
全局执行上下文对象作用域是全局; 函数内执行上下文对象作用域是所在函数。

3. 闭包

3.1 什么是闭包?

1)简单讲,闭包就是指有权访问另一个函数作用域中的变量的函数。
2)MDN 上面这么说:闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。

3.2 如何产生闭包

1. 函数A中嵌套函数B
2. 函数B中访问函数A中定义的数据(上层作用域的变量)
3. 实现从函数A的外部使用函数B
方式一: 将函数B作为返回值
方式二: 将函数B赋值给全局对象的属性
方式三: 将函数B作为一个事件的回调函数
function A() {
// 定义数据
var num01 = 100, num02 = 200;
// 函数B
function B(){
// 函数B中可以访问到函数A中的数据
console.log(num01 + num02);
}
// 方式一 函数B作为返回值
return B; // 方式二 函数B赋值给全局对象的属性
// window.func = B; // 方式三 函数B作为事件的回调函数
// document.onclick = B;
}

3.3 闭包和作用域

1. 可以访问上层作用域的数据
2. 作用域只与函数声明的位置有关,与调用位置无关

3.4 闭包和垃圾回收

闭包延长了数据的生命周期

3.5 闭包的缺点

闭包会让数据常驻内存,增加了内存溢出的风险

3.6 闭包的应用

 for (var i = 0; i < tabNavItems.length; i ++) {
(function(index){
tabNavItems[index].onclick = function() {
// 排他
// 把所有的tabNav都取消选中 把所有的tabContent隐藏
for (var j = 0; j < tabNavItems.length; j ++) {
tabNavItems[j].classList.remove('active');
tabContentItems[j].classList.remove('active');
} // 当前点击的选项卡导航添加 active 类名 表示当前选中
this.classList.add('active');
// 与当前tabNav对应的tabContent要显示出来
tabContentItems[index].classList.add('active');
};
})(i);
}

4. 对象高级

4.1 原型链总结

① 原型和构造函数

1. 构造函数.prototype 可以获取到该构造函数实例的原型
2. 构造函数相同的对象,原型也相同

__proto__ 和 prototype 属性

1. 函数类型的对象
__proto__ : 获取的是自己的原型
prototype: 获取的该构造函数的实例的原型 2. 其他类型的对象
__proto__: 获取的是自己的原型
没有 prototype 属性

③ construct 属性

本身具有constructor属性的对象,会作为其他对象的原型,constructor的值就是其他对象的构造函数

④ 原型链

// 自定义的构造函数
function Foo() {} // Foo 的两个实例
var f1 = new Foo();
var f2 = new Foo(); // Object的两个实例
var o1 = {};
var o2 = {};
f1、f2 -> Foo.prototype -> Object.prototype
o1、o2 -> Object.prototype
Foo、Object、Function -> Function.prototype -> Object.prototype

特殊现象(不是规则,不要记,要理解)

1. Object 的原型是 Function.prototype, Function.prototype 的构造函数是 Object
2. Function 的构造函数是 Function, 所以 Function.prototype === Function.__proto__

4.2 面向对象继承

① 面向对象编程语言的继承规则

// 父类(对应的就是js中的构造函数)
class Foo{
private name;
private age;
public getInfo() {}
} // 子类
class Product extends Foo {
private address;
} // 子类
class Shopcart extends Foo { }

② JS 中继承关系的特点(原型继承特点)

1. 对象可以继承它的原型上的属性
2. 对象的构造函数、它的原型的构造函数也可以描述成子类、父类的关系
1. 对象a的原型是对象b, 对象a的构造函数是子类,对象b的构造函数是父类
子类的实例以父类的实例为原型
2. 一个对象只能有一个原型,原型可以作为多个对象的原型
一个父类可以有多个子类, 一个子类只能有一个父类

③ 实现JS中构造函数和构造函数之间继承(子类 父类)

原理:

1. 设置子类的实例的原型是父类的一个实例
2. 设置子类的实例的原型的 constructor 属性的值是子类
function A(){}
function B(){} // B作为子类 A作为父类
// 设置B的实例的原型是 A的一个实例
B.prototype = new A();
// 设置 B.prptotype 的 constructor 属性
B.prototype.constructor = B;
Array是子类 Object是父类
1. Array的实例的原型 是Object的一个实例
2. Array.prototype.constructor 是 Array

实现:

 // 定义商品类
function Product(price, nums) {
// 给实例设置属性
this.price = price;;
this.nums = nums;
}
Product.prototype.discount = function(num) {
this.price *= num;
};
Product.prototype.buy = function() {
this.nums -= 1;
} // 汽车类商品
function CarProduct(price, nums, speed) {
// this.price = price;
// this.nums = nums;
// 将父类规定的属性添加到了 CarProduct 的实例上
Product.call(this, price, nums);
this.speed = speed;
}
// 设置 CarProduct 的实例的原型是 Product 的一个实例
CarProduct.prototype = new Product();
// 设置 CarProduct 的实例的的原型的 constructor 属性的值是 CarProduct
CarProduct.prototype.constructor = CarProduct;
// 设置方法
CarProduct.prototype.driver = function() {
console.log('这辆车可以被驾驶!');
}

5 单线程和事件轮询机制

5.1 进程和线程

进程:
程序的一次执行, 它占有一片独有的内存空间 线程:
CPU的基本调度单位, 是程序执行的一个完整流程 进程和线程:
* 一个进程中一般至少有一个运行的线程: 主线程。
* 一个进程中也可以同时运行多个线程, 我们会说程序是多线程运行的。
* 一个进程内的数据可以供其中的多个线程直接共享。
* 多个进程之间的数据是不能直接共享的。

5.2 JS 单线程运行

1. 如何证明JavaScript是单线程执行?
设置了定时器,定时器的回调函数会等到主线程空闲且时间到执行;
如果主线程没有空闲下来,即使定时器的时间到了,回调函数也不会执行(等到主线程空闲)。 2. 为什么JavaScript选择单线程?
多线程会有线程调度以及线程开启关闭的开销
JavaScript主要在浏览器端操作DOM完成特效,如果不是单线程,不好解决页面渲染的同步问题。

5.3 同步任务和异步任务

同步任务:
按照顺序,一步一步地执行,执行完上一个任务再执行下一个任务 异步任务:
需要满足条件且主线程空闲才可以执行,在等待异步任务满足条件的过程中,同步任务继续执行, 异步任务会在同步任务完成后执行
异步任务都是回调函数的形式, 回调函数不一定都是异步任务 JS中的异步任务有哪些:
1. 定时器的回调函数
2. DOM事件的回调函数
3. Ajax的回调函数
4. Promise的回调涵数
....

5.4 事件轮询机制

1、执行栈(调用栈)
主线程里就是一个执行栈,所有的任务都要放入执行栈执行 2、异步任务管理模块
判断异步任务是否满足了执行条件,分为:
定时器管理模块
DOM事件管理模块
Ajax管理模块
...
如果满足了异步任务管理模块,会将异步任务放入回调队列,等待执行 3. 回调队列
队列是一种数据存储结构,特点是先进先出,后进后出
回调队列存放等待执行的异步任务 4. 事件轮询模块
时刻监听主线程(执行栈)是否空闲,一旦空闲,从回调队列中取出异步任务,放入主线程执行

6 JS 实现多线程(了解)

Worker 构造函数
Worker.prototype.postMessage() 向分线程发送数据
Worker.prototype.onmessage 监听分线程的消息

学习JavaScript第六天的更多相关文章

  1. 一步步学习javascript基础篇(0):开篇索引

    索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...

  2. 一步步学习javascript基础篇(8):细说事件

    终于学到事件了,不知道为何听到“事件”就有一种莫名的兴奋.可能是之前的那些知识点过于枯燥无味吧,说起事件感觉顿时高大上了.今天我们就来好好分析下这个高大上的东西. 可以说,如果没有事件我们的页面就只能 ...

  3. 一步步学习javascript基础篇(7):BOM和DOM

    一.什么是BOM.什么是DOM BOM即浏览器对象模型,主要用了访问一些和网页无关的浏览器功能.如:window.location.navigator.screen.history等对象. DOM即文 ...

  4. 学习javascript数据结构(三)——集合

    前言 总括: 本文讲解了数据结构中的[集合]概念,并使用javascript实现了集合. 原文博客地址:学习javascript数据结构(三)--集合 知乎专栏&&简书专题:前端进击者 ...

  5. 学习javascript数据结构(二)——链表

    前言 人生总是直向前行走,从不留下什么. 原文地址:学习javascript数据结构(二)--链表 博主博客地址:Damonare的个人博客 正文 链表简介 上一篇博客-学习javascript数据结 ...

  6. 学习javascript数据结构(一)——栈和队列

    前言 只要你不计较得失,人生还有什么不能想法子克服的. 原文地址:学习javascript数据结构(一)--栈和队列 博主博客地址:Damonare的个人博客 几乎所有的编程语言都原生支持数组类型,因 ...

  7. 《如何正确学习JavaScript》读后小结

    在segmentfault上读的一篇学习JavaScript路线的文章,做个小结. 一.简介.数据类型.表达式和操作符 (1)<JavaScript权威指南>前言1-2章&< ...

  8. 一步步学习javascript基础篇(6):函数表达式之【闭包】

    回顾前面介绍过的三种定义函数方式 1. function sum (num1, num2) { return num1 + num2; }  //函数声明语法定义 2. var sum = funct ...

  9. 一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)

    上一篇介绍了对象创建的几种基本方式,今天我们看分析下对象的继承. 一.原型链继承 1.通过设置prototype指向“父类”的实例来实现继承. function Obj1() { this.name1 ...

  10. 一步步学习javascript基础篇(4):面向对象设计之创建对象(工厂、原型和构造函数等模式)

    前面我们介绍了可以通过Object构造函数或对象字面量都可以用来创建单个对象,但是如果需要创建多个对象的话,显然很多冗余代码. 接下来介绍几种模式来创建对象.不过在此之前,我们还是先来了解下 type ...

随机推荐

  1. 运维 + AI,你得先搞懂这些

    很感谢夜莺提供如此优质的平台能和行业内顶尖技术大佬做面对面的交流,在这个会议中又学习到了很多有趣有深度的内容,给我在未来探索的道路上提供了一些新的指引方向.同时感谢夜莺社区的邀请,在此再做一次关于AI ...

  2. Infinity颜值与实用兼备的新标签页,高效书签管理必选的浏览器扩展

    浏览器是我们互联网冲浪的必备平台,但是在使用浏览器的过程中,我们经常会遇到标签页和书签管理的问题.过多的标签页和书签会导致浏览器变得杂乱无章,不利于我们快速查找需要的内容.为了提高我们的工作和学习效率 ...

  3. 2. 基于MCU应用的EMC指南

    1. 硬件 主要的噪声感受器和发生器是印刷电路板(PCB)上的轨道和布线,特别是MCU附近的轨道和布线.因此,防止噪声问题的第一步行动涉及到PCB布局和电源设计.一般来说,MCU周围的元器件数量越少, ...

  4. 为什么用Vite框架?来看它的核心组件案例详解

    Vite 是一个前端构建工具,它以其快速的开发服务器和生产优化的打包器而闻名前端界,今天的内容,必须得唠唠 Vite 的关键能力,以下是 Vite 的核心组件分析,以及使用案例: 原理分析: Vite ...

  5. Win32 插入符光标跟随的打字小程序

    1.先创建插入符光标 在WM_CREATE消息中 LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) { HDC hdc = GetDC ...

  6. 常见 URI 协议

    mailto mailto 是一种 URI(统一资源标识符)协议,主要用于在 Web 页面中创建电子邮件链接.当用户点击使用 mailto 协议的链接时,系统会自动打开默认的电子邮件客户端,并在新邮件 ...

  7. 【Python后端开发】Flask之ORM数据库操作

    一.前言 ORM 对象映射关系程序. 通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直 ...

  8. RocketMQ 下载安装及消息发送

    消息队列前文目录链接参考: 消息队列初见:一起聊聊引入系统mq 之后的问题https://www.cnblogs.com/yizhiamumu/p/16573472.html 分布式事务实战方案汇总  ...

  9. Blazor开发框架Known-V2.0.10

    Known今天迎来了2.0的第11个版本,同时网站网址和板块也进行了一次升级改造,虽不完美,但一直在努力改变,之前一直在完善框架功能,忽略了文档的重要性,所以这次更新了文档和API.交流互动板块也在进 ...

  10. TS2Vec: 面向通用的时间序列表示《TS2Vec: Towards Universal Representation of Time Series》(时间序列、对比学习、多尺度特征(池化操作)、分层对比、上下文一致性(时间戳掩码+随机裁剪))

    今天是2024年5月22日,10:24,今天看这篇经典的论文(如果你问我为什么最近频繁看论文,因为我的创新点无了,要找创新点+太菜了,菜就多看多学). 论文:TS2Vec: Towards Unive ...