Git Product home page Git Product logo

deep-javascript-v3's Introduction

Table Of Content

v8引擎基本原理

  • 编译器: Compiler
  • 解释器: Interpreter
  • 抽象语法树: AST
  • 字节码: Bytecode
  • 即时编译器: JIT

编程语言类型

编译型语言

在执行程序之前,会将代码编译成为二进制文件;每次运行时只需要运行二进制文件即可,无需重新编译,C/C++, GO等都是编译型语言。生成过程会占用大量内存,因为有中间代码的产生。

解释型语言

先将源代码翻译成字节码,然后逐行解释执行;每次运行时都需要通过解释器对程序动态解释及执行; 生成过程不会占用大量内存,因为字节码比中间代码小很多。

V8

  • 生成AST: tokenize, parse
  • 生成执行上下文
  • 解释器Ignition将AST生成字节码
  • 执行代码(JIT)
    • 如果是第一次执行该代码,则Ignition逐行解释执行
    • 如果遇到HotSpot代码,则TurboFan进入编译,保存为高效的二进制文件

内存空间

代码空间

  • 用来存储可执行代码

栈空间

  • 先进后出以维护执行上下文顺序
  • 对上下文切换效率有要求,只适合存储型数据: primitive, reference
  • 垃圾回收由ESP指针下移来实现

堆空间

  • 适合存储型数据,内存分配和回收会消耗一定时间
  • 存储对象(闭包), 内存泄露发生在这里
  • 垃圾回收由GC来完成, 会被分割成为新生代(副垃圾回收器 Scanvenger算法)和老生代(主垃圾回收器,增量标记算法)

执行上下文

何时开始

  • 全局运行
  • 调用函数(编译阶段只会将函数存储到堆中)
  • 运行eval()

生命周期

  • 代码编译: 函数调用或者全局才会进入编译;
    • 创建变量环境: var(提升定义和初始化-undefined)
    • 创建词法环境: 块级作用域由词法作用域中的小型栈来维护
      • let(只提升定义,状态为uninitialzied),
      • const(只提升定义,状态为uninitialized)
      • func 声明(提升且直接赋值,本身存储在heap中; 会覆盖掉同名变量, 但是可以重新赋值)
      • func 表达式(提升定义和初始化-undefined)
      • func 参数(初始化-undefined)
    • 确定词法作用链: 看源代码就能确定: (具体实现是有outer引用实现的)
      • 全局作用域
      • 函数作用域
      • 块级作用域
      • 对象并不构成作用域
    • 确定this指向: new > apply/call/bind > object context > gloabl/undefind
  • 代码执行
    • 函数参数赋值
    • 标识符赋值(const未赋值会报错,let未赋值会默认为undefined)
    • 函数调用(会创建新的执行上下文)
  • 垃圾回收
    • 调用栈中的垃圾回收是靠ESP指针下移来实现的(不是GC)

闭包

定义

  • 在JavaScript 中,根据词法作用域的规则,内部函数总是可以访问其外部作用域中声明的变量,当通过调用一个外部函数返回一个内部函数后,即使该外部函数的执行上下文已经销毁,但是内部函数引用的其外部的变量依然以对象的形式保存在内存堆中,我们就把这些变量的集合称为闭包。比如外部函数是foo,那么这些变量的集合就称为foo函数的闭包
  • 闭包的本质是返回函数及其所引用的外部变量,外部变量的查询依然遵照作用域链的原则

产生

  • 编译期间: 预先扫描函数、
  • 遇到函数时,要先预扫描一遍
  • 如果引用外部变量,则会形成闭包的引用,这是闭包并未在内存中建立
  • 只有

例子

  • 1号栗子
function a() {
  const x = 123;
  function b(){
    console.log(x);
  }
  return b;
}
a()(); // x 是b()的闭包;
  • 2号栗子
var bar = {
    myName:"time.geekbang.com",
    // 不会close over上面的myName,因为上层是对象
    printName: function () {
        console.log(myName)
    }    
}
function foo() {
    let myName = "极客时间"
    return bar.printName
}
let myName = "极客邦"
let _printName = foo()
_printName()
bar.printName()

作用

  • 数据封装(data as private)
  • 工厂模式(Factory Pattern)
  • 模块基础(Module Pattern)

销毁

  • 伴随着引用它的函数的销毁而销毁
  • 如果引用闭包的函数是一个全局变量,则闭包会一直存在直到页面关闭,因此可能会造成内存泄露
function play1() {
  const x = 1;
  console.log(x);
}
function get(){
  return play1;
}
get()();
  • 如果引用闭包的函数是个局部变量,等函数销毁后,在下次 JavaScript引擎执行垃圾回收时,判断闭包这块内容如果已经不再被使用了,那么JavaScript引擎的垃圾回收器就会回收这块内存。
const x = 1;

function play1() {
  console.log(x);
}

function get(){
  function play2() {
    console.log(x);
  }
  return play2;
}

get()();
  • 如果该闭包会一直使用,那么它可以作为全局变量而存在;
  • 如果使用频率不高,且占用内存较大的话,那就尽量让它成为一个局部变量;
  • 可以沟通设置闭包函数为null来释放闭包

this

设置优先级

  • new
  • call/bind/apply 死绑定
  • object context
  • global or Window(non-strict)/undefined(strict)

解决this太活跃的问题

  • 保存thisself变量然后传入(从外层到内层)
  • 使用Arrow Function

本质上都是将this机制转化为scope chain机制

Arrow Function

  • 会创建新的执行上下文
  • 会创建新的作用域
  • 从外部函数返回后,会产生闭包
  • this的查找依赖于Scope Chain
var myObj = {
  name : "极客时间", 
  showThis: function(){
    console.log(this)
    var bar = () => {
      this.name = "极客邦"
      console.log(this)
    }
    bar()
  }
}
myObj.showThis()
console.log(myObj.name)
console.log(window.name)

注意的点

  • 函数调用时才会对其进行编译
  • 函数编译时,变量和内部函数声明会被赋值,var定义及初始化为被提升,let,const的定义会被提升,不会被初始化。
  • 变量和函数重名时,函数提升优先级更高; 但是可以被重新赋值
alert(a);//输出:function a(){ alert('我是函数') }
function a(){ alert('我是函数') }//
var a = '我是变量';
alert(a);   //输出:'我是变量'
  • let在未赋值后使用,将自动化初始化为undefined
let b;
console.log(b);

deep-javascript-v3's People

Contributors

dependabot[bot] avatar geekeast avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

yujiay

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.