JS 事件循环机制
同步任务队列
异步任务队列
- 宏任务包括:
setTimeout, setInterval, setImmediate, I/O, UI rendering
- 微任务包括:
process.nextTick, promise.then, MutationObserver
- 宏任务包括:
- 同步和异步任务进入不同的执行位置,同步进入主线程,异步进入事件表并注册函数
- 当指定的事情完成后(强调),事件表会将此功能移动到事件队列
- 主线程中的任务执行完后为空,去事件队列中读取对应的函数,进入主线程执行
- 不断重复上述过程,通常称为事件循环(eventloop)。
js面向对象的理解
- 对象:一切都是对象
- 类:对象的细分
- 示例:课堂上的具体事物
js 为什么是单线程而不是多线程
进程
:CPU资源分配的最小单位; (是能够拥有资源并独立运作的最小单位)线程
:是CPU调度的最小单位; (线程是基于进程的程序运行单元,一个进程中可以有多个线程)
浏览器是一个多进程
放在浏览器中,每次打开一个标签页,其实都是一个新的进程,在这个进程中有ui渲染线程,js引擎线程,http请求线程等等。因此,浏览器是一个多进程。
JavaScript 的主要目的是与用户交互并操作 DOM。这就决定了它只能是单线程的,否则会造成非常复杂的同步问题。例如,假设JavaScript同时有两个线程,一个线程向某个DOM节点添加内容,另一个线程删除这个节点,那么浏览器应该以哪个线程为基础呢?
为了利用多核CPU的计算能力,HTML5提出了Web Worker标准,该标准允许JavaScript脚本创建多个线程,但子线程完全由主线程控制,不得操作DOM。因此,这个新标准并没有改变 JavaScript 的单线程本质。
js垃圾处理机制
内存管理:“可达性”
,指的是可以以任何方式访问或使用的值,它们保证存储在内存中。
- 具有一组固有的可实现值,由于明显的原因无法删除,
这些值称为根
。示例:
- 局部变量和局部函数的参数
- 当前嵌套调用链中其他函数的变量和参数
- 全局变量 还有其他一些,里面
- 如果引用或引用链可以达到根 的任何其他值,则认为该值是可访问的。
垃圾回收器,它监视所有对象,并删除那些不可访问的对象
- 什么是污垢?
一般来说,没有被引用的对象是垃圾,必须删除。有一个例外。如果一些对象引用形成一个环并互相转向,但根无法访问它们,那么这些对象也是垃圾,必须删除。 - 如何控制乱扔垃圾?
- 标记-清除算法 标记-清除GC
- 垃圾收集器获取根并“标记”(记住)它们。
- 然后访问它并“标记”其中的所有引用。
- 然后它访问标记的对象并标记它们的引用。所有访问过的对象都会被记住,这样同一个对象以后就不会被访问两次。
- 依此类推,直到有未访问的引用(可通过 root 访问)。
- 除标记的对象外,所有对象均被删除。

- 标记紧凑型 标记紧凑型
- 参考编号
- GC复制算法
- 保守GC
- 世代回收
- 增量GC
如果要继承,必须提供一个父类(从谁继承,给出继承的属性)
- 原型链继承:
让新实例的原型等于父类的实例。
特点
- 实例可以继承的属性包括:实例构造函数的属性、父类构造函数的属性、父类原型的属性。 (新实例不会继承父类实例的属性!)
-
- 新实例无法向父类构造函数传递参数。
- 继承是单一的。
- 所有新实例共享父类实例的属性。 (原型属性是共享的。如果一个实例更改原型属性,则另一实例的原型属性也会更改!)
- 信用构造函数(类继承):
用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
– 特点
:
1。只继承父类构造函数的属性,不继承父类原型的属性。
2。修复了原型链继承的缺陷1、2、3。
3。您可以继承多个构造函数属性(调用更多)。
4。子实例中可以向父实例传递参数。
– 缺点
:
1。只能继承父类构造函数的属性。
2。无法实现构造函数重用。 (每次使用都要重新调用)
3。每个新实例都有一个父类构造函数的副本,该副本是臃肿的。
- 组合继承(组合原型链继承和借用构造函数继承)(常用)
结合了两种模式的优点,传参和复用
特点
:- 可以继承父类原型上的属性,传递参数并复用。
- 引入的每个新实例的构造函数属性都是私有的。
缺点
:父类构造函数被调用两次(消耗内存),子类构造函数替换原型上的父类构造函数。
- 原型继承
重点
:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了一个实例或者一个可以随意添加属性的对象。 object.create()就是这个原理。特点
:类似于复制对象并用函数包装它。- :
- 所有实例都继承原型的属性。
- 无法实现重复利用。 (稍后会添加新的实例属性)
- 寄生遗传
重点
:是给原型继承披上一层外壳。优点
:没有创建自定义类型,因为它只是一个返回对象(this)的外壳,这个函数自然会创建一个新对象。缺点
:原型未使用,无法重复使用。
- 寄生组合遗传(常用)
寄生
:在函数中返回一个对象,然后调用组合
:1.函数的原型等于另一个实例。 2.在函数中使用apply或者call引入另一个构造函数,可以传递参数重点
:修复了构图继承问题
// 父类---------------------------
function Person(name){ //给构造函数添加参数
this.name=name
this.sayName =function(){
alert(this.name)
}
}
Person.prototype.age = 18; //给构造函数添加了原型属性
// 原型链继承---------------------------
function Per(){
this.name = 'panpan';
}
Per.prototype= new Person(); //重点
var per1 = new Per();
console.log(per1.age); // 18
// instanceof判断元素是否在另一个元素的原型链上
console.log(per1 instanceof Person); //true
// 借用构造函数继承---------------------
function Con(){
Person.call(this,'ava'); //重点
this.age = 21
}
var con1 = new Con()
console.log(con1.name) //ava
console.log(con1.age) //21
console.log(con1 instanceof Person) //false
// 组合原型链继承和借用构造函数继承
function SubType(name){
Person.call(this,name); //借用构造函数模式
}
SubType.prototype= new Person(); //原型链继承
var sub = new SubType('lian')
console.log(sub.name) //lian 继承构造函数属性
console.log(sub.age) //18 继承父类原型属性
// 原型式继承---------------------------
// 先封装1个函数容器,用来输出对象和承载继承的原型
function content(obj){
function F(){}
F.prototype=obj; //继承传入的参数
return new F() //返回函数对象
}
var sup = new Person(); //拿到父类的实例
var sup1 = content(sup)
console.log(sup1.age) //18 继承父类函数属性
// 寄生式继承----------------------
// 给原型式继承再套个壳子传递参数
function subObject(obj){
var sub = content(obj)
obj.name= 'pan';
return sub
}
//声明后成了可增添属性的对象
var sup2 = subObject(sup)
console.log(typeof subObject) //function
console.log(typeof sup2) //object
console.log(sup2.name) //pan
// 寄生组合式继承---------------------
// 寄生
function content(obj){
function F(){}
F.prototype=obj; //继承传入的参数
return new F() //返回函数对象
}
// content就是F实例的另一种表达
var con = content(Person.prototype)
// con实例(F实例)的原型链继承了父类函数的原型
// 上述更像原型链继承,只不过继承了原型属性
// 组合
function Sub(){
Person.call(this) // 继承父类构造函数属性
} //解决组合式2次调用构造函数属性的缺点
// 重点
Sub.prototype = con; //继承con实例
con.constructor = Sub; //一定要修复实例
var sub1 = new Sub();
// Sub实例继承了构造函数属性、父类实例、con的函数属性
console.log(sub1.age)
锁定
闭包主要用于设计私有方法和变量。闭包的优点是避免污染全局变量。缺点是闭包会保留在内存中并增加内存使用量。使用不当很容易造成内存泄漏。在js中,函数就是闭包,只有函数才有作用域的概念
闭包具有三个属性:
- 功能嵌套功能
- 函数可以引用外部参数和变量
- 参数和变量不会被F垃圾回收机制回收
new 运算符 它到底有什么作用?
- 创建一个空对象,这个变量引用该对象,同时也继承了函数的原型。
- 属性和方法被添加到它引用的对象中。
- 新创建的对象被 this 引用,并且 this 在最后隐式返回。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。