欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

前端进阶必读:《JavaScript核心技术开发解密》核心提炼

程序员文章站 2022-03-21 08:28:26
前言最近读勒基本关于前端的数据《JavaScript核心技术开发解密》,《webpack从入门到进阶》…这几本书帮助到我更好的理解JS、webpack在前端技术领域中的作用。以前可能更多的是知道怎么使用,但从未从更深的层面去思考他们是如何运作,为什么会产生这种特性,等等…这本书先从《JavaScript核心技术开发解密》开始讲解,读完这本书你能学到:一、三种基础数据结构栈(stack)堆(heap)队列(queue)不要小看这些数据结构,他们不同的结构以及规则产生了我们平常所知道的一些特性:...

前言

最近读勒基本关于前端的数据《JavaScript核心技术开发解密》,《webpack从入门到进阶》…这几本书帮助到我更好的理解JS、webpack在前端技术领域中的作用。以前可能更多的是知道怎么使用,但从未从更深的层面去思考他们是如何运作,为什么会产生这种特性,等等…
这本书先从《JavaScript核心技术开发解密》开始讲解,分为两篇讲完,读完本篇你能学到:

前端进阶必读:《JavaScript核心技术开发解密》核心提炼二
前端进阶必读:《JavaScript核心技术开发解密》核心提炼三

一、三种基础数据结构

  • 栈(stack)
  • 堆(heap)
  • 队列(queue)
    不要小看这些数据结构,他们不同的结构以及规则产生了我们平常所知道的一些特性:先进先出,对象赋值是传递引用,消息队列等等…

1.1栈

  • 场景1:数据结构,一种存取方式
  • 场景2:规定代码的执行顺序,在JS中叫函数调用栈(call stack)
  • 场景3:数据存储的位置(栈区),但JS中并没有区分堆区、栈区,所以可以简单的认为数据是都存在堆内存中
    先进先出
    前端进阶必读:《JavaScript核心技术开发解密》核心提炼

1.2堆

堆数据结构通常是一种树状结构
无顺序

var people = {
	name: 'a',
	age: 12,
	father: {
		name: 'b',
		age: 28,
	};

1.3队列

在JS中,理解队列数据结构,可以很好的理解时间循环(event loop)机制是怎么个原理。
先进先出
前端进阶必读:《JavaScript核心技术开发解密》核心提炼
这个知识点应该大部分人都知道,也没啥难度,不过耐心。高级的东西就是基本的知识复杂的组合起来的。

二、内存空间

JS有垃圾自动回收机制

2.1基础数据类型与变量对象

在最新的es标准中,定义了7种数据类型(6种基础+1种引用)

6种数据类型 备注
Boolean
Null
Undefined
Number
String
Symbol 目前很多浏览器不支持

重点来了
案例:

function fn () {
	var a = 10;     
	var b = '11';
	var c = null;
}

函数在运行时,会创建执行环境(执行上下文),在其中会创建变量对象VO,这些基础数据往往都存在这个对象中
前端进阶必读:《JavaScript核心技术开发解密》核心提炼
你可能对变量对象有很多疑问,这里稍作解释:变量对象可以暂时理解为:当函数执行时会将该函数压入函数栈中,这个过程会创建执行上下文,并且创建与执行上下文对应的变量对象,该变量对象可以存储该函数产生的变量等作用。

以上这段话要好好理解一下,因为他还与作用域链的原理有关

2.2 引用数据类型与内存空间

ES中定义的第七种类型:引用数据类型
引用类型Object存在堆内存中,不能直接访问,而是通过引用地址来操作。
前端进阶必读:《JavaScript核心技术开发解密》核心提炼

var a = 'bar';
var b = a;   // 基本类型是直接复制栈内存中的数据,也就是bar
var c = {p:1};
var d = c;   // 引用类型同样是复制栈中的数据,但此时栈中存的是执行{p:1}这个对象在堆中的地址

2.3内存空间管理

JS中现在使用
标记清除算法:不能够被获取得数据会被打上标记并回收
描述:该算法会设置一个全局对象,并定期从全局对象开始查找,回收器会获取可以访问以及不能被访问的数据。
注意:在局部作用域中,当函数执行完毕后,局部变量也没有存在的必要,因此回收期很容易判断,执行完毕就回收。但在全局中就较难判断,所以减少全局变量,也可微妙提升性能;不用就a=null,确保能及时回收。

三、执行上下文

这个知识点非常牛逼,一定要会!到后面的this指向啥的原本以为较复杂的,这就一目了然了。以及作用域链、变量对象、活动对象都与这个知识点息息相关。

在JS的执行中,会进入下一个执行上下文(当前运行环境),JS中的运行环境主要包括以下三种情况:

三种情况 Value
全局环境 代码运行后,首先进入全局环境
函数环境 函数代码执行时
eval环境 不建议用

上下文以“”的方式处理
案例:

// demo.js
function fn1 () {
	var n = 999;
	function fn2 () {
		alert(n);
	};
	return fn2;
}
var result = fn1();
result();   // 999

以上代码会在函数栈中发生下面的变化:::
前端进阶必读:《JavaScript核心技术开发解密》核心提炼

3.3生命周期

当一个函数调用时,一个新执行上下文就会创建,它的生命周期分为两个阶段:

  • 创建
  • 执行
执行上下文生命周期 描述
创建 上下文分别创建变量对象,确认作用域链,以及确定this指向
手机 创建阶段之后,则执行代码,这个时候会完成变量赋值,函数引用,及其他代码

还是要搞个图图,帮助记忆(用叠词就是可可爱爱的)
前端进阶必读:《JavaScript核心技术开发解密》核心提炼
另外:let/const在生命在执行期间完成

是不是又理解了一点let/const为什么没有发生不会发生变量提升的问题了。
不急,接着看!

四、变量对象

4.1 创建过程

  1. 依次获取上下文中所有function关键字生命的函数并赋值
  2. 依次获取上下文中的变量生命var关键字。初始化为undefined,如果该变量已存在,则跳过,原始值不会改变

好好解读这句话,这里面就是变量提升的过程了,并且定义的变量其实都是在变量对象当中。而且是 function的优先级高于var,并且var不能覆盖原有的。

接下来好好看看下面的案例!!!

var a= 20;
function fn () {console.log('fn')};
function fn () {console.log('cover fn')};
function a() {console.log('cover a')};

console.log(a);
fn();

var fn = 'i want fn';
console.log(fn);

将问题拆分为创建时,与执行是

// 创建时,先提升function,再提升var
function fn () {console.log('fn')};
function fn () {console.log('cover fn')};
function a () {console.log('cover a')};

var a = undefined;    // var定义的,a已存在,所以不覆盖
var fn = undefined;   // var定义的,fn已存在,所以不覆盖 

// 执行时
var a = 20;
console.log(a);       //20
fn();                // cover fn

var fn = 'i want cover fn';
console.log(fn);    // i want cover fn

!!!一定要好好理解var 与function提升的区别,并且明白创建时与执行时的不同作用。

4.2 全局上下文的变量对象

它有个特殊的地方,即它的变量对象就是window对象,而且全局上下文的变量对象不能变成活动对象!

windowEC = {
	VO : window,
	scopeChain: [];
	this: window;
}

另外:全局上下文与程序生命周期一致,其他所有上下文环境都直接访问全局上下文的属性。

本文地址:https://blog.csdn.net/bigname22/article/details/107465318