【深入理解JS|青训营笔记】

28 阅读3分钟

一.js的基本概念

1.进程种类:Browser进程,GPU进程,渲染进程,插件进程,网络进程等。 其中渲染进程又分为GUI线程,js线程,事件触发线程,定时器触发线程,网络线程

2.缺优点:GUI线程和JS线程不能同时进行,动态弱类型,安全性强,性能差(边解释边执行)

3.数据类型:复杂和基础两种类型 复杂类型存地址,基础类型存变量的值,当更改复杂类型值时,关联的地址其值也会变化

4.作用域-静态作用域 三种:全局作用域,函数作用域,块级作用域(用“{}”)表示

5.变量提升-var 只有var有,浏览器会先浏览一遍代码,遇到var时会先在前面给var定义成undefined,后面再赋值

ps:

function函数可以先调用后定义

二.JS是怎么执行的

1.过程 源码-AST-字节码(节约内存)-机器码(重复执行两次以上存储)

2.执行上下文(执行环境) 全局执行上下文:每个生命周期只有一份 函数执行上下文:执行结束后从栈顶弹出

ps:

执行上下文会创建变量环境,词法环境

Outer指向外部变量环境的指针(上一级,直到可使用)

ESP(记录当前执行状态的指针)

三.JS进阶知识点

1.闭包

这是从网络上找出的两部分代码及说明

第一部分

  function init() {

  var name = "Mozilla"; // name 是一个被 init 创建的局部变量
  
  function displayName() { // displayName() 是内部函数,一个闭包

  alert(name); // 使用了父函数中声明的变量
  
  }

  displayName();

  }

init();

init() 创建了一个局部变量 name 和一个名为 displayName() 的函数。displayName() 是定义在 init() 里的内部函数,并且仅在 init() 函数体内可用。请注意,displayName() 没有自己的局部变量。然而,因为它可以访问到外部函数的变量,所以 displayName() 可以使用父函数 init() 中声明的变量 name 。

这个例子是为了说明变量的引用

第二部分

function makeFunc() {

    var name = "Mozilla";

    function displayName() {

        alert(name);
    
    }

    return displayName;
    
}

var myFunc = makeFunc();
myFunc();

运行这段代码的效果和之前 init() 函数的示例完全一样。其中不同的地方(也是有意思的地方)在于内部函数 displayName() 在执行前,从外部函数返回。

原因在于,JavaScript 中的函数会形成了闭包。 闭包是由函数以及声明该函数的词法环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。在本例子中,myFunc 是执行 makeFunc 时创建的 displayName 函数实例的引用。displayName 的实例维持了一个对它的词法环境(变量 name 存在于其中)的引用。因此,当 myFunc 被调用时,变量 name 仍然可用,其值 Mozilla 就被传递到alert中。

2.this (1)普通this指向windows

(2)对象调用指向对象,但如果是先赋值后调用,看调用的地方

(3)一种用法:

1.创建临时对象

2.this指向临时对象

3.执行构造函数

4,返回临时对象

屏幕截图 2023-05-01 082115.png

3.垃圾回收:新生代和老生代

新生代:1.垃圾回收 2.对象复制 3.区域翻转(两次没有被回收放入老生代)

老生代:1.标记对象 2.清除标记对象 3.数据整理(清除时js停顿不执行)