美文网首页
02-1 | 读JavaScript 高程 | 解释

02-1 | 读JavaScript 高程 | 解释

作者: cemcoe | 来源:发表于2020-05-07 21:24 被阅读0次

上篇说了对于 JavaScript,预处理 + 执行 = 解释,解释没那么简单,那么究竟什么是解释?

解释解释

你来解释解释什么是解释?

什么,TMD的是解释?


什么是解释

本来打算有空就写的,结果苟了几天,没有写了,感觉自己废了。

主要是这个解释,难以解释。

黄四郎:好啊!三天之后,一定给县长一个惊喜!
张麻子:汤师爷,他是胡万的恩人,现在又成了你的恩人!你给翻译翻译,什么叫惊喜?翻译翻译,什么叫惊喜?
汤师爷:这还用翻译?都说了…
张麻子:我让你翻译给我听,什么叫惊喜!
黄四郎:不用翻译,就是惊喜啊!难道你听不懂什么叫惊喜?
张麻子:我就想让你翻译翻译,什么叫惊喜!
汤师爷:惊喜嘛……
张麻子:翻译出来给我听,什么他妈的叫惊喜!什么他妈的叫他妈的惊喜!
汤师爷:什么他妈的叫惊喜啊?
黄四郎:惊喜就是三天之后,我出一百八十万,给你们出城剿匪,接上我的腿!明白了吗?
汤师爷:这就是惊喜呀
张麻子:翻译翻译。翻译翻译!
汤师爷:惊喜就是三天之后,给你一百八十万两银子,出城剿匪,接上他的腿!
张麻子:大哥这个是惊喜啊!小弟我愿意等你三天。(拉过汤师爷来)黄老爷,汤师爷是我的至爱,你可不能夺我所爱啊!
黄四郎:了然,了然!

心态炸了,有没有?

解释

这玩意怎么解释

解释 = 预处理 + 执行,解释这个东西要怎么解释?

书上没有呀,这时可以拿起另一本书 你不知道的JavaScript(上卷) 来看一看。

预编译过程

来看一个例子:

// eg1
console.log('a', a)
var a = 123

console.log('---')

var b = 123
console.log('b', b)

console.log('---')

console.log('c', c)
/**
 * a undefined
 * ---
 * b 123
 * Uncaught ReferenceError: c is not defined at index.js:11
*/

我们知道在 ES6 中可以使用 const 和 let 定义变量,将上边的 var 换成 const 会出现什么的情况?

// eg2
console.log('a', a)
const a = 123

console.log('---')

const b = 123
console.log('b', b)

console.log('---')

console.log('c', c)
/**
 * Uncaught ReferenceError: Cannot access 'a' before initialization at index.js:1
*/

直接报错,这是因为 ES6 中的 const 和 let 会形成暂时性死区,这就是另外一个故事了。

回到 var 上面来,令人迷惑的是下面的代码片段:

// eg3
console.log('a', a)
const a = 123

console.log('c', c)

如上面的代码所示,a 和 c 都是在没有被声明时调用了,但 a 得到的是 undefined,而 c 却报错了。

两者的区别在于 a 最后补上了声明,而 c 始终没有声明。a 给人的感觉就是我先用,声明先欠着,等到某天我会还上的。而 c 完全就没有想要补上声明的意思。

看一个例子

再来看一个例子,控制台会输出什么?

// eg4
console.log(a)

function a(a) {
  var a = 234
  var a = function() {}
  a()
}

var a = 123
/**
 * ƒ a(a) {
 * var a = 234
 * var a = function() {}
 * a()
 * }
* /

有一种刚学会 1+1 就要去做微积分的感觉。

来预编译

再来一题:

// eg5
function fn(a) {
  console.log(a) // f a() {}
  var a = 123
  console.log(a) // 123
  function a () {}
  console.log(a) // 123
  var b = function () {}
  console.log(b) // f () {}
  function d() {}
}

fn(1)

口说无凭,打个断点调试一下。


打个断点

真刺激。


打个断点

预编译发生在函数执行的前一刻。

预编译四部曲

  1. 创建 AO 对象 Activation Object 执行期上下文
  2. 找形参和变量声明,将变量和形参的名挂上,并赋值undefined
  3. 将形参和实参相统一
  4. 找函数声明,赋值函数体

下面是例子 eg5 产生 AO 的过程:

1.
AO {

}

2.
AO {
  a: undefined,
  b: undefined,
}

3.
AO {
  a: 1,
  b: undefined
}

4.
AO {
  a: function a() {},
  b: undefined,
  d: function d() {}
}

在代码执行时上哪里找a?就是上面的 AO,接下来按顺序就好了。预编译调和各个变量的冲突。在运行过程中,AO 也会动态变化。


走一遍流程:

// eg6
function test(a, b) {
  console.log(a)
  c = 0
  var c 
  a = 3
  b = 2
  console.log(b)
  function b () {}
  function d () {}
  console.log(b)
}
test(1)
// 走流程
1. 创建AO对象
AO {

}
2. 找形参和和变量声明并赋值undefined
AO {
  a: undefined
  b: undefined
  c: undefined
}
3. 人剑合一,将形参和实参相统一
AO {
  a: 1,
  b: undefined
  c: undefined
}
4. 找函数体声明赋值函数体,会覆盖第三步
AO {
  a: 1
  b: function b() {}
  c: undefined
  d: function d() {}
}

拿着我们的 AO 去和函数对线,打印顺序是122.

我们来提炼一下,在预处理时,赋值函数体在形参和实参统一的后边,变量的赋值是在函数执行时发生的。

练习

ok,来道题练一练,下面的console都会打印什么东西?

// eg7
function test(a, b) {
  console.log(a)
  console.log(b)
  var b = 234
  console.log(b)
  a = 123
  console.log(a)
  function a () {}
  var a 
  b = 234
  var b = function () {}
  console.log(a)
  console.log(b)
}
test(1)

不墨迹,直接写AO对象。

AO {
  a: function a() {}
  b: undefined
}

很简单,接下来拿着 AO 按照顺序执行就好了。

对于全局而言全局生成GO Global Object,再来个复杂的题目。

// eg8
console.log(test)
function test(test) {
  console.log(test)
  var test = 234
  console.log(test)
  function test() {}
}
test(1)
var test = 123

直接 AO GO 写起来。

GO {
  test: test(test){}
}

AO {
  test: test() {}
}

简单。,,这就是解释还没完,有空再写。

相关文章

  • 02-1 | 读JavaScript 高程 | 解释

    上篇说了对于 JavaScript,预处理 + 执行 = 解释,解释没那么简单,那么究竟什么是解释? 解释解释 你...

  • 05 | 读JavaScript 高程

    这是第五章引用类型,这一章涉及引用类型的种类,各个类型身上的方法等相关内容。 主要知识点: 1.引用类型和类和对象...

  • 01 | 读 JavaScript 高程

    缘起 总感觉自己前端的知识体系不是很系统,打算读一下这本很多人推荐的书,从目录来看第三版有些东西在2020年可能已...

  • 02 | 读 JavaScript 高程

    今天来瞧一瞧第二章在 HTML中使用 JavaScript script 标签属性的变化 首先是 script 标...

  • 03 | 读JavaScript 高程

    这是第三章基本概念,这一章涉及变量,操作符,语句和函数等相关内容。 主要的知识点: ECMAScript 中究竟有...

  • 06 | 读JavaScript 高程

    这是第六章面向对象的程序设计,这一章涉及到一些概念和思想,也是 JavaScript 中很重要的知识点。需要注意的...

  • 04 | 读JavaScript 高程

    这是第四章基本概念,这一章涉及变量、作用域和内存问题等相关内容。主要知识点: 值类型和引用类型的区别是什么? 如何...

  • 08 | 读JavaScript 高程

    这一篇呢是第8章,主要涉及 BOM 的相关知识。 先来看BOM,即和浏览器相关地一些东西。 知识点:1.BOM 中...

  • 07 | 读JavaScript 高程

    这是第七章函数表达式,这一章涉及函数预编译,闭包,作用域链内容。函数涉及内容繁多。 前情提要 02-1 | 读Ja...

  • 13 | 读JavaScript 高程 | 事件

    这一篇呢是第13章,内容是和事件相关。 事件可以看成是条件判断的一种条件,逻辑是某个元素发生了某个事情,我要做出相...

网友评论

      本文标题:02-1 | 读JavaScript 高程 | 解释

      本文链接:https://www.haomeiwen.com/subject/judeghtx.html