[摘录总结]JS砖瓦篇

微信扫一扫,分享到朋友圈

[摘录总结]JS砖瓦篇

原型

原型对象

在现代浏览器中,函数本身拥有 prototype
属性,当用函数作为构造函数构建实例后,该属性指向一个对象,这个对象包含创建的实例多共享的属性和方法,同时,创建的实例中也会有 __proto__
属性指向构造函数的该对象,这个对象就是原型对象。

原型链

当 js 对象无法寻找到对应的属性或方法时,都会通过 __proto__
向其构造函数的原型对象上查找,直到找到源头 Object 对象为止,形成了一个原型指向的链条,就是原型链。

数据类型

堆与栈

数据类型与堆栈息息相关,首先了解一下堆栈概念。

- 数据结构中,栈是先进后出的结构,而堆优先队列的结构
- 操作系统中,栈内存由编译器自动分配释放,对内存由程序员分配释放
复制代码

基本数据类型

直到现在的 ES10 版本,基本数据类型共七种:null, undefined, boolean, string, number, symbol, bigint,都存放在栈中。

symbol

symbol 是在 es6 标准中提出的,主要解决对象中键名重复的问题

number

typeof NaN

结果是 number,代表不是一个数字

isNaN 与 Number.isNaN

前者会存在一个问题,会将参数转换为数值,而不能转换的都会返回 true,比如 ‘a’,这样会存在问题。解决方法就是使用 Number.isNaN,这种方式会先确认是不是数字,然后判断 isNaN,更加准确。

bigint

bigint 是在 es10 标准中提出,解决大数据(值超过 2^53 – 1)超出安全范围的问题

undefined

与 undeclared 区别

- undefined 代表变量未定义,不同于 undeclared 的未声明,后者引用会报错,而前者不会
- undefined 可以引用, undeclared 引用会报 引用错误
复制代码

与 null 区别

- undefined 与 null 都是基本数据类型,null 代表空对象
- null 是保留字,不能作为变量名,而 undefined 可以
- typeof,undefined 是 'undefined',而 null 是 'object'
复制代码

获取安全的 undefined 值

void(0),void __ 没有返回值,因此返回结果为 undefined
复制代码

null是对象吗

不是。typeof null 的结果是 ‘object’,这里是一个历史问题。以 000 开头的是对象,然而 null 本身就是全 0,导致 typeof 判断错误

boolean 与 假值对象

浏览器创建的外来值,就是‘假值对象’,比如 document.all,这种值与普通对象很像,但是强制转换为布尔值结果为 false

假值对象

复杂数据类型

复杂数据存在着疑问,一般认为泛指 Object,但是在 typeof function 的情况下,返回值是 ‘function’,所以我觉得 应该包括Object 和 Function,甚至。它们存在堆中,比较值得注意的是,闭包变量应该也存在堆中,我们后面讨论。

内置对象 [[class]]

对象在没有自定义 toString() 方法的情况下,执行 toString() 会输出内置对象 [[class]]的值,比如数组输出[Object Array]

闭包

闭包有很多版本的解释,我采用红宝书中的定义:闭包是指有权访问另一个函数作用域中的变量的函数。
当我们在一个函数A中常见另一个函数B,B能访问到A的局部变量,形成了闭包。这样做有什么好处呢:

- 可以通过外部调用闭包函数,访问到函数内部的局部变量,这种局部变量就类似于私有变量供使用了
- 已经结束运行的函数上下文中的变量依旧留在内存中,闭包保留这个变量对象的引用,避免变量对象回收
复制代码

通过第二条,就会发现一个很有意思的现象,闭包函数执行完,仍然保留变量对象,该对象的基本数据类型值依然留在内存中,不符合栈中数据在函数执行结束后就销毁的特性。之所以会这样,是因为闭包保留着对变量的引用。所以闭包变量存放在堆中。

数据转换

其他值转为字符串的转换规则

  • null 和 undefined类型,转回为 ‘null’, ‘undefined’
  • boolean类型,’true’ 和 ‘false’
  • number,直接转为支付串形式
  • Symbol 可以显示强制类型转为,隐式转换会报错
  • 普通 Object,首先查看有无自定义 toString 方法,有的话就调用并使用返回值,没有就调用toString方法,返回内部属性[[class]]

其他值转为数值的转换规则

  • undefined 转为 NaN
  • null 转为 0
  • boolean,true 为 1,false 为 0
  • string,空为 0,有非数字字符,返回 NaN,否则转为数字
  • Symbol 不能转为数字
  • Object,会先进行抽象操作 ToPrimitive,首先检查 valueOf() 方法,如果返回基本类型就再转化,否则查看 toString() 方法,如果返回基本类型就再转化,否则会报错

其他值到布尔类型转换

  • undefined
  • null
  • false
  • +0, -0,NaN
  • 假值对象
    以上为false,其他为真值

== 操作符的强制类型转换规则

  • 字符串与数字比较,字符串转为数字
  • 其他类型和布尔类型比较,现将布尔值转为数字,再引用规则
  • null 和 undefined 相等,但与其他值不相等
  • 对象与非对象比较,对象先调用 ToPrimitive 抽象操作后在比较
  • NaN 不等于任何值,包括本身
  • 凉的对象比较,如果指向同一对象,则相等,否则不等

+操作符拼接

当其中一个操作数是字符串,或者能够通过(ToPrimitive)抽象操作为字符串的,则进行拼接,否则执行加法。

执行

V8 垃圾回收

V8 内存限制

64位系统中,基本电脑的内存很大,V8 也只是分配到1.4G内存,那么是什么原因使得V8 内存限制,这么少的内存又是如何支撑起浏览器运行的呢。
首先,基于 js 单线程以及 js 垃圾回收机制的限制,不需要太大的内存,其次,V8 采用限制堆内存,解决垃圾回收好事的问题,下面,以垃圾回收为终点进行研究。

垃圾分类

现在深圳也开始进行垃圾分类了(鼓掌),那么v8是如何分类的呢:V8 将内存分为新生代内存和老生代内存。然我们看看这里面卖的什么药。

新生代内存回收

新生代内存是临时分配的内存,存回事件短。
64位系统下,新生代内存仅占32MB,它通过 From 与 To 两部分倒腾,实现小块内存处理新生代内存回收:
1.首先正在使用的内部放在 From 区,目前闲置的内存放在 To 区。
2.进行牢记回收时,V8 检查 From 区的对象,将存活对象复制到 To 区,非存活对象回收。
3.当 From 区倒腾完之后,From 与 To 互换。
复制代码

To 区接受 From 区产生的内存碎片问题

To 区采用 Scavenge 算法,将零散的内存整合为连续的内存,这样能够方便后面内存的分配,解决碎片问题
复制代码

老生代内存回收

老生代内存存活时间长,通过新生代内存晋升形成,形成方式为:
1.经历过一次 Scavenge 回收
2.To空间超过 25% 的内存
老生代采用增量标记法来完成,分为两步
1.进行标记-清除:遍历对重的所有对思昂,将其中一部分做上标记,然后对代码中使用的变量
以及强引用的变量取消标记,在随后的清除阶段对标记的变量进行空间回收
2.整理内存碎片,将存活对象全部往一端靠拢。接着暂停回收,执行js逻辑,然后再进行第一步
这样做的好处是比原本全部标记的方法减少到 1/6 的时间。
复制代码

事件循环

浏览器中将任务分为宏任务和微任务。

宏任务

setTimeout、setInterval、setTmmediate(只兼容ie)
复制代码

微任务

then 、messageChannel 、mutationObersve
复制代码

执行过程

1. 所有代码作为一个宏任务执行
2. 执行过程中同步代码执行,宏任务进入宏任务队列,微任务进入微任务队列
3. 宏任务执行完出队,然后检查微任务队列,有则依次自行,直至为空
4. 执行浏览器 UI 线程的渲染工作
5. 检查是否有 web worker 任务,有则执行
6. 执行队首新的宏任务,接着第二部,直至所有宏任务与微任务队列为空
复制代码

微信扫一扫,分享到朋友圈

[摘录总结]JS砖瓦篇

Vue单文件项目自定义组件入门

上一篇

信通院:2020年8月国内市场5G手机出货量1617万部

下一篇

你也可能喜欢

[摘录总结]JS砖瓦篇

长按储存图像,分享给朋友