JTangming / blog

My repository on GitHub.
Other
53 stars 0 forks source link

关于编译和执行 #43

Open JTangming opened 4 years ago

JTangming commented 4 years ago

编译和执行

历史上,计算机语言分为两组:静态语言(例如,Fortran 和C,其中变量类型是在编译时静态指定的)和动态语言(例如,Smalltalk 和JavaScript,其中变量的类型可以在运行时改变),主要区别是变量类型的确定。

静态语言通常编译成目标机器的本地机器代码(或汇编代码)程序,该程序在运行时直接由硬件执行。动态语言由解释器执行,不产生机器语言代码。

后来,虚拟机(VM)的概念开始流行,它其实只是一个高级的解释器,虚拟机使语言移植到新的硬件平台更容易。因此,VM 的输入语言常常是中间语言。例如,一种编程语言(如 Java )被编译成中间语言(字节码),然后在VM( JVM )中执行。

另外,现在有即时(JIT)编译器。JIT 编译器在程序执行期间运行,即时编译代码。而原先在程序创建期间,运行时之前执行的编译器称为 AOT 编译器。

一般来说,静态语言才适合 AOT 编译为本地机器代码,因为机器语言通常需要知道数据的类型,而动态语言中的类型事先并不确定。因此,动态语言通常被解释或 JIT 编译。

在开发过程中,AOT 编译开发周期长(从更改程序到能够执行程序以查看更改结果的时间),总是很慢。但是 AOT 编译产生的程序可以更可预测地执行,并且运行时不需要停下来分析和编译。AOT 编译的程序也更快地开始执行(因为它们已经被编译)。

与此相反的是,JIT 编译提供了更快的开发周期,但可能导致执行速度较慢或时快时慢。特别是,JIT 编译器启动较慢,因为当程序开始运行时,JIT 编译器必须在代码执行之前进行分析和编译。

以上就是背景知识。

Reference

JTangming commented 4 years ago

箭头函数和类普通函数、constructor 里 bind 的函数有什么区别

class funcs {
    constructor() {
        this.fun_b = this.fun_b.bind(this);     
    }

    fun_a() {
        console.log('a');
    }
    fun_b() {
        console.log('b')
    }
    fun_c = () => {
        console.log('c')
    }
}

babel 编译后:

// ...
var funcs =
/*#__PURE__*/
function () {
  function funcs() {
    _classCallCheck(this, funcs);

    _defineProperty(this, "fun_c", function () {
      console.log('c');
    });

    this.fun_b = this.fun_b.bind(this);
  }

  _createClass(funcs, [{
    key: "fun_a",
    value: function fun_a() {
      console.log('a');
    }
  }, {
    key: "fun_b",
    value: function fun_b() {
      console.log('b');
    }
  }]);

  return funcs;
}();

从编译结果可得出结论:

class 内对于 = 号声明的方法、变量,都会将其作为实例的属性,而对于非 = 号声明的属性,则是放在原型链上,在继承方面需要多加留意。

JTangming commented 4 years ago

babel-handbook