接前面Qt中的JavaScript引擎小记,继续梳理javascript基础知识。
比如,写了一个javascript程序,该如何执行它,需要什么东西?
1 2 3 4 5 6 7 |
|
本文目标:在Firefox、Node.js、Qt、Python下,分别执行上面的脚本。
注意:在这个例子中,
console
并不是ECMAScript规范的一部分,而是由运行时提供的(好在各个运行时基本都提供了该功能)。
基本概念
- JavaScript引擎(Engine):一种将 JavaScript 代码转换为可执行代码的程序组件,它负责解释和执行 JavaScript 代码。早期的引擎只是解释器,但现代的引擎都使用JIT(just-in-time compilation)来改善性能。知名的引擎有:V8、JavaScriptCore、SpiderMonkey、 ...
- JavaScript运行时(Runtime):JavaScript的运行环境,包括JavaScript引擎、标准库、宿主环境等。不同的运行时为JavaScript执行提供不同的资源,比如网络浏览器和Node.js都是运行时。浏览器提供文档对象模型(DOM)和浏览器对象模型(BOM)等API;Node.js提供文件系统操作、网络操作等API。
在 Qt上:QJSEngine和QScriptEngine 都是 JavaScript引擎,而使用这两个类的Qt程序则是 JavaScript 运行时。不同的Qt程序为javascript提供不同的资源(暴露不同的API给javascript)。
是否可以这样类比C++:把引擎理解成不带任何库函数的编译器,把运行时理解成编译器+库函数?
引擎 与 运行时
JavaScript的主战场是浏览器,引擎基本都是浏览器厂商开发的。
浏览器
运行时 | 引擎 | 备注 |
---|---|---|
Chrome | V8 | |
Firefox | SpiderMonkey | |
Edge | V8 | 早期(2015年之前?)曾使用自己的 Chakra |
Safari /səˈfɑːri/ | JSC (JavaScriptCore) | 2008年Apple重写JSC后,内部代号 Nitro |
Opera | V8 | 早期(2013年Opera15之前)使用自己的 Carakan、Futhark、Linear B |
IE | Charkra | 早期(IE9之前)使用自己的 JScript |
JavaScript 只是一个单线程的编程语言,这意味着:它只有一个调用栈, 一次只能做一件事情。
服务端
额,不清楚为什么很多人叫服务端,这不就是脱离浏览器的JavaScript运行环境吗?为了和浏览器(客户端)相对应??
运行时 | 引擎 | 备注 |
---|---|---|
Node.js | V8 | |
Deno | V8 | |
Bun | JSC (JavaScriptCore) |
Qt
在Qt中,出现过两个JavaScript引擎,共四种实现:
- QScriptEngine: Qt4.3时是自己实现的,Qt4.6时内部切换到JavaScriptCore,Qt5.5时废弃,Qt6.0时移除。
- QJSEngine: Qt5.0时内部使用V8引擎,Qt5.2时切换到Qt自己的引擎V4。
其他
wikipedia给出了数十种引擎。用于嵌入式的、用于java的、用于rust的 ...
如何运行javascript
回归初衷,如果要测试一个javascript,该如何运行?
浏览器
浏览器是javascript最主要的运行环境,如何用
放入 html 页面中
而后在浏览器中通过界面元素进行触发(botton点击、body加载 等):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
注意,<script>
可以放在页面不同位置上:
<head>
中:可以确保脚本在页面加载前执行,但可能导致阻塞页面渲染。<body>
底部:提升加载性能<head>
中使用defer
属性:推迟执行,直到页面加载完毕。(避免阻塞页面加载)
为了保持通用,此处刻意没有用alter()等弹窗函数(它是浏览器这种运行时特有的)。
不过,执行是执行了,可是console把内容输出到什么地方去了??
在console中直接执行
JavaScript中console的输出,需要在console中才能看到。在Windows下,快捷方式如下:
浏览器 | 快捷键(Windows) | 备注 |
---|---|---|
Chrome | Ctrl+Shift+J | |
Firefox | Ctrl+shift+K | |
Edge | Ctrl+Shift+J |
既然打开console了,其实,在这里面可以执行javascript代码的。以Firefox为例
- 支持单行js、多行js、js文件
- Ctrl+O 打开js文件
- Ctrl+Enter 执行当前脚本
服务端
以node.js为例。将如下代码保存为 t.js
1 2 3 4 5 6 7 8 9 |
|
执行它:
1 |
|
Qt
编写程序,调用 QJSEngine,编译运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
- 因为console并不是ECMAScript规范一部分,QJSEngine提供该功能,需要通过扩展方式开启。
Python
Python下轮子多,值得一试。
- Python中一个的js2py包,但是只支持ECMA5.1。所以下面的脚本不能跑通:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
- 使用pythonmonkey运行,没有问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
参考
- https://en.wikipedia.org/wiki/JavaScript_engine
- https://en.wikipedia.org/wiki/List_of_ECMAScript_engines
- https://sayansarkar333.medium.com/advance-javascript-working-of-javascript-engine-3c36c1a46f50
- https://dev.to/sanderdebr/a-brief-explanation-of-the-javascript-engine-and-runtime-2idg
- https://www.codecademy.com/article/running-javascript-in-the-browser-console
- https://firefox-source-docs.mozilla.org/devtools-user/web_console/the_command_line_interpreter/index.html
- https://doc.qt.io/qt-6/qjsengine.html