chrome Console 自动输出的是什么东西
如图所示“<” 这些自动输出的是什么?要本质,能用js的什么函数可以模拟输出。尤其是最后一个输出b,返回“<a{}”.展开可以看b的 proto 。但是直接访问是访问不到的。
Answers
Chrome Console 是一个 REPL 环境。
通俗地理解 REPL 环境就是,它就接受你输入的一个表达式,然后执行,最后输出执行结果 —— 也就是你看到的
<·
后面的内容。
一个表达式由操作符和操作数组成,操作符又叫运算符(例如 =、+、-、&),所以一个表达式通常又可以称为一次“运算”。比如
1+2
这样一个由加法操作符和1、2这两个操作数组成的表达式,通常被称为一次加法运算(或加法操作)。运算都是有一个结果的,这个结果就是执行这个表达式得到的返回值。
而为什么输入形如
var a
,
var a = 1
,
function a() { return 1; }
这样的代码只会得到 undefined 呢? 因为它们
不是表达式,它们是语句
(并且上面列举的3个都属于声明语句),
语句是没有返回值的
(return 语句必须用在 function 里来指定其返回值,是一种特殊情况)(如错请纠正!)。
再进一步。
为什么直接输入
123
,
12.34
,
'abc'
,
[1,2,'34']
,
true
这样的直接量(在 JavaScript 也可称为字面量)时, REPL 也能把它们原模原样地输出呢?
简陋版回答:
因为在 Chrome Console 里输入任何代码,再按回车,都相当于把这段代码作为参数传给
eval
函数然后执行,而执行 eval 之后的结果就是这样。我知道这个回答简直跟没说一样,而且似乎还引出了先有鸡还是先有蛋的问题。
较真版回答:
我们来看 REPL 的 R(Read) 究竟做了什么:
读入函数接收一个来自于用户的表达式,将其解析成数据结构并存入内存。例如,用户可能会输入一个s-表达式 (+ 1 2 3),这句话会被解析成一个包含四个元素的链表。
就是把一个表达式的操作符和操作数按照解释的顺序存到了内存里。那么,当我们仅仅输入操作数时,也就只把操作数存到了内存里。
我们再看 REPL 的 E(Evaluate) 究竟做了什么:
求值函数 负责处理内部的数据结构并对其求值。在Lisp中,求一个以函数名开头的s-表达式意味着对接下来的参数调用那个函数。所以函数"+"被在参数1 2 3上调用,产生结果6。
上面这段文字中的“函数”我认为可以理解为“操作数”。因为我们并没有输入操作数,所以 REPL 环境跳过了这一步。直接来到第三步 —— “Print” (即 REPL 的 P)。此时内存里只有我们一开始输入的直接量,所以也就只能输出它了。
恩,细心的朋友可能已经想到了:为什么没提到对象字面量呢? 因为只输入对象字面量得不到你预期的结果(如果你读到这了,不妨动手试一试)。 为什么不行呢?因为 JavaScript 语法的设置。(请看 MDN 上的解释 )
PS. 以上只是我对 JavaScript 的概念以及 REPL 的解读,如果有错误或不清晰的地方,恳请修正完善。
推荐阅读:
- 什么是 REPL(
Wikipedia
)。
- JavaScript 里的运算符(
MDN 上的文档
)。
- JavaScript 里的语句(
MDN 上的文档
)。