Day18_Senior课堂笔记

Day18 JavaScript 高级笔记

1 回顾

1.1 垃圾回收机制

- 引用计数 -
- 标记清除 -

1.2 执行上下文和执行栈

① 执行上下文对象
全局执行上下文对象:
① 代码执行之前创建,将全局执行上下文对象赋值给 window
② 预处理:
  变量提升
  函数提升
  this 赋值
③ 正式执行全局代码

函数的执行上下文对象:
① 调用函数的时候创建执行上下文对象
② 预处理:
  形参赋值
  arguments 赋值
  局部变量提升
  局部函数提升
  this 赋值(调用函数的对象)
③ 正式执行函数体代码
② 执行栈
1. 特点: 先进后出,后进先出
2. 用于存储执行上下文对象

1.3 闭包

1. 闭包概念
   使用其他函数作用域中的数据,称为闭包
2. 如何产生闭包
   ① 函数A中嵌套函数B
   ② 函数B中使用函数A中的数据
   ③ 函数B对外引用(返回、赋值给全局变量、作为回调函数)
3. 闭包与作用域的关系
   ① 可以使用上层作用域的数据
   ② 作用域只与函数声明位置有关
4. 闭包与垃圾回收
   闭包延长了数据的声明周期
5. 闭包缺点
   增加了内存泄漏的风险

2 对象高级

2.1 原型链总结

__proto__ 和 prototype 属性
1. 任何对象都有 __proto__ 属性,通过该属性可以获取自己的原型。
2. 只有函数才具有 prototype 属性,该属性获取函数的实例的原型。
3. 一般情况 函数.prototype 与 函数.__proto__ 绝对不等。
   特殊情况 Function.prototype === Function.__proto__; Function 的构造函数还是 Function。
② constructor 属性
1. 并不是所有的对象都有 constructor 属性,需要使用原型上的 constructor 属性
2. 本身具有 constructor 属性的对象,它的 constructor 指向并不是自己的构造函数,而是以它为原型的那些个对象的构造函数
3. 对象本身没有constructor属性,可以通过原型的 constructor 获取自己的构造函数
   对象本身有 constructor 属性,并不是给自己用的,给以它为原型的那些个对象用的
③ 原型链
// 定义构造函数
function Foo() {
    
}
// 实例化 Foo
var f1 = new Foo();
var f2 = new Foo();

// 实例化 Object
var o1 = new Object();
var o2 = new Object();
f1、f2 -> Foo.prototype -> Object.prototype
o1、o2 -> Object.prototype
Foo、Object、Function -> Function.prototype -> Object.prototype

prototype 和 __proto__

f1.__proto__ === Foo.prototype;
Foo.prototype.__proto__ === Object.prototype;
o1.__proto__ === Object.prototype;
Foo.__proto__ === Function.prototype;
Object.__proto__ === Function.prototype;
Function.__proto__ === Function.prototype;

本身的 constructor 属性:

Foo.prototype.constructor === Foo;
Object.prototype.constructor === Object;
Function.prototype.constructor === Function;

2.2 面向对象继承

① 面向对象语言的继承规则
// 作为父类
class User {
    // 定义属性 实例的属性
    private username;
    private age;
    // 定义方法
    say() {
        
    }
}

// 定义子类
class VipUser extends User {
	// 定义属性
    private address;
}
② JS 中继承关系的特点
1. JS 中依靠原型链进行集成,对象可以使用原型链上的属性和方法。
2. intanceof 运算符判断对象和自己构造函数,对象和原型链上的对象的构造函数,都成立。
3. 对象的 __proto__ 等于它构造函数的 prototype
4. 如果一个对象本身具有 constructor 属性,指向以该对象为原型的那些对象的构造函数。
5. JS 是单继承, 一个对象只能有一个原型,一个对象可以给多个对象当原型。
③ 实现JS中构造函数和构造函数之间继承
// 定义构造函数 作为父类
function User(username, age) {
    // 对形参进行判断
    if (age < 0 || age > 200) {
        age = 0;
    }

    // 给实例添加属性
    this.username = username;
    this.age = age;
}
// 在实例的原型上添加方法
User.prototype.addShopcart = function() {
    console.log(this.username + '把商品添加到购物车!');
};
User.prototype.buy = function(product) {
    console.log(this.username + '买了' + product);
};


// 定义构造函数 作为子类 继承 User
function VipUser(username, age, address) {
    // 调用 父类中对属性赋值的操作
    User.call(this, username, age);
    // 添加子类自己实例的属性
    this.address = address;
}

// 设置VipUser的实例的原型 是 User的一个实例
VipUser.prototype = new User();
// 给VipUser的实例的原型设置 construct 属性
VipUser.prototype.constructor = VipUser;

VipUser.prototype.getInfo = function() {
    console.log('我叫' + this.username +', 年龄:'+this.age+',地址:'+ this.address);
};

1. 让子类的实例的原型指向父类的一个实例(最重要)
2. 给子类的实例的原型设置属性 constructor 属性,指向子类(构造函数)
3. 子类中,使用 call 调用父类,设置父类中的 this 指向子类的实例。

2.3 安全的类型检测

function getType(data) {
    var typeStr = Object.prototype.toString.call(data);
    return typeStr.slice(8, typeStr.length - 1);
}

3 单线程和事件轮询机制

3.1 进程和线程

进程:
	程序使用内存的最小单位,一个进程独占一块内存空间。
	
线程:
	线程是 CPU 的最小调度单位。
	

进程和线程:
	1. 一个进程可以同时运行多个线程,多线程运行
	2. 进程中至少有一个线程,主线程
	3. 同一个进程中的多个线程之间可以直接共享数据,共用一块内存
	4. 不同进程之间,无法直接共享数据。

3.2 JS 单线程运行

1. JS 是单线程运行的,一各时刻只能进行一个计算任务
2. JS 为什么设计为单线程?
   多线程会有线程调度以及线程开启关闭的开启
   JavaScript在浏览器上操作DOM,如果不是单线程,不好解决渲染同步问题。

3.3 同步代码和异步代码

1. 同步代码
   同步代码,同步任务,安装顺序依次执行,上一个任务结束下一个任务开始
   
2. 异步代码
   异步代码,异步任务,满足条件且线程空闲才能执行的任务。
   
3. 哪些是异步任务?
   ① 定时器的回调函数
   ② DOM 事件的回调函数
   ③ Ajax 的回调函数
   ④ Promise 的回调函数
   
4. 注意事项:
	① 异步任务通常都是回调函数的形式,回调函数不一定是异步任务。
	② 开启定时器、监听事件等操作是同步任务。

3.4 事件轮询机制

1. 执行栈
   在主线程中,所有的任务(不论是同步任务还是异步任务)都在执行栈里面执行
   
2. 异步任务管理模块
   包括定时器管理模块、DOM事件管理模块、Ajax管理模块等, 负责监听异步任务(回调函数)是否满足执行条件
   
3. 回调队列
   满足执行条件的异步任务会进入回调队列,等待执行。
   队列的特点: 先进先出,后进后出
   
4. 事件轮询模块(Event Loop)
   负责监听执行栈是否空闲,一旦空闲,从回调队列中将异步任务依次放入执行栈执行

4 JS 实现多线程(了解)

1. 利用 Worker, JS 中可以实现多线程运行
2. 多线程运算适合耗时地计算,在子线程中计算不影响主线程
3. 子线程中无法使用 BOM、DOM
Worker 构造函数
Worker.prototype.postMessage()			向子线程发送数据
Worker.prototype.onmessage				事件,监听子线程发回数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人生本该如此

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值