JS 理解 6

JS执行机制

1 预编译: 把当前作用域内的, var变量声明和函数声明, 提升到作用域的最前面去执行

2 执行列队
  1 先执行执栈中的同步任务 -> 把遇到的异步任务交给异步处理进程 -> 然后由异步处理进程决定放入任务队列的时间 -> 触发时才会放入
  2 等执行栈中的同步任务执行完毕 -> 再依次读取任务列队中等待的异步任务 -> 放入执行栈中开始执行
  3 主线程 -> 执行栈 -> 不断重复获取任务列队的任务并执行, 这种循环的机制被称为 --> 事件循环 (event loop)
  
3 知识点
  1 对于定时器, 只有等待时间过了, 才会被异步进程写到任务列队里面
  2 对于事件, 只有触发了, 才会被异步进程写到任务列队里面
  3 在事件列队中优先执行微任务, 然后执行宏任务, ajax只要请求到数据就放在第一位执行  (ajax不是微任务, 也不是宏任务)

同步 / 异步

1 同步异步出现之前, 遇到的问题: 
  1 JS 是单线程, 同一时间只能做一件事, 上一个任务结束, 下一个任务才可以开始
  2 这样就导致了, 如果某段代码执行时间太长, 就会导致后面的代码无法执行, 也就是加载阻塞

2 同步异步的出现 (解决了加载阻塞的问题)
  1 把我们的任务分为了俩大类: 同步 / 异步
  2 同步任务: 都放在主线程上按照单线程的方式执行的, 形成一个执行栈
  3 异步任务: 通过回调函数实现的, 放在异步队列里面等待执行的任务
  4 常见的异步任务: 事件监听 / 定时器 / Promise / ajax / async .. 

作用域

1 理解: 
  1 就是一块独立的区域空间
  2 一个作用域内的代码和变量, 对该作用域外部的环境, 毫无影响

2 存在作用域的地方: js文件, script标签, 函数内部, ES6的大括号

3 关于作用域的生命周期: 
  1 全局作用域: 进入页面创建, 关闭页面销毁
  2 局部作用域: 函数执行的时候创建, 执行完毕销毁

4 作用域链: 
  1 内部作用域可以访问外部作用域, 且遵守就近原则
  2 作用域 a内部创建作用域b, b可以访问a中的变量, a不可访问b中的变量
  3 如上关系, 层层嵌套的作用域, 就被称之为作用域链

堆和栈

1 栈内存: 
  1 是用于存放简单类型数据的一个内存空间
  2 存放的简单数据指向我们定义的变量
  3 重新赋值会覆盖原有值, 原有数据不会销毁, 只是没有指向了 (所以尽可能不要频繁修改)

2 堆内存: 
  1 是用于存放复杂类型数据的一个内存空间
  2 堆内存的数据, 会生成索引放在栈中指向变量, 
  3 修改复杂类型的数据, 所有指向它的变量结果都会同步改变
  4 如果不想被改变, 就需要深复制一个新的复杂类型数据 (对象), 去使用
  5 或者直接让变量指向一个新的数据

闭包

1 产生原因: 
  1 俩个相互嵌套的函数, 内部函数作用域访问了外部函数作用域中的变量
  2 当内部函数被 return到外部, 声明变量接收且执行的时候
  3 这个函数会在执行体处访问它所在环境的外部函数的变量
  4 这个访问的过程, 或者被访问的函数, 就叫做闭包

2 作用
  1 延申了变量的作用范围
  2 实现封装, 属性私有化 (防止污染全局变量)

3 危害: 
  1 正常情况那个外部函数在不执行的时候, 内部变量是销毁状态的, 
  2 闭包会导致原有作用域链不释放, 变量未被销毁, 造成内存泄漏  (即使内存占用过多) 

4 简单实现闭包的代码
    function a() {
      var x = 9
      function b() {
        console.log(x);
      }
      return b
    }
    
    var hh = a()
    hh()  // 9

原型

1 概念
-------------------------------------------------------------------------------------
1 我们把 JS中的对象分为 普通对象 和 函数对象
2 函数对象都有 prototype 原型属性 – Function.prototype 除外 – 普通对象没有该属性
3 所有函数都是 Function() 构造函数的实例 – Function.prototype == fn / Function.prototype.prototype == ubdefined
4 prototype 的主要作用 – 所有添加到原型对象上的属性方法, 都将被所有实例对象共享 – 就是继承
5 对象都有 proto 隐藏属性 – 主流浏览器自带的, 不是给开发者用的
6 对象都有 constructor 属性 – 属性值为该对象的构造函数或类
7 根构造器 Object – Object.prototype.hh = 777 --> 所有对象都可以访问 hh了
8 原型链 – 就是多个原型之间的特殊的访问关系
9 prototype==JS的原型对象 / proto 浏览器自带的原型对象
-------------------------------------------------------------------------------------

2 原型之间的关系
-------------------------------------------------------------------------------------
1 理解
	1 obj.__proto__ == obj构造器的 prototype   -- 一个对象可访问它原型链上的所有属性和方法 
	2 构造器的 __proto__ == ƒ () { [native code] }
	3 Object == 根构造器
	4 Object.prototype == 原型链的末端     // 例 -- 所有对象可以使用 toString() 的原因就是, 该方法存在于原型链的末端
	5 Object.prototype.__proto__ == null     // 说明根构造器的原型对象没有构造器

2 常见场景
	1 创建字符串 -- var str = "zhang"
	2 原型指向 -->  str.__proto__ == String.prototype
	3 原型指向 -->  String.prototype.__proto__ === Object.prototype   //记住 String这类构造器的 __proto__ 就是直接指向原型链子末端的
	4 原型指向 -->  Object.prototype.__proto__ === null

4 案例解析
	1 Object.prototype.hh = 77   -->  var str = "zhang"  --> console.log(str.hh)  // 77
	2 浏览器通过原型链查找 hh 属性过程
		1 str.hasOwnProperty('abc')   false  
		2 str.__proto__.hasOwnProperty('abc')   false
		3 str.__proto__.__proto__.hasOwnProperty('abc')   true -> 返回 hh 的属性值 66
		4 str.__proto__.__proto__ == String.prototype.__proto__ == Object.prototype
-------------------------------------------------------------------------------------

3 继承
-------------------------------------------------------------------------------------
1 继承的方式
  1 构造函数继承 有局限性…
  2 原型继承 不合常理…
  3 拷贝继承 父子对象都会受到影响…
  4 混合继承 常用的实现继承方式
  5 class类继承 常用的实现继承方式
-------------------------------------------------------------------------------------

构造函数

用于创建特定类型的对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值