https://zhuanlan.zhihu.com/p/34191831
醉了,一个玩具项目那么多 star.好吧,近期我把这东西代码和注释完善一下,不追求一定能工业应用,但至少能做出一个教学级别项目给大家展示设计思路,保证不辜负这么多 star.
简易的 JavaScript 元循环解释器
https://zhuanlan.zhihu.com/p/34191831
醉了,一个玩具项目那么多 star.好吧,近期我把这东西代码和注释完善一下,不追求一定能工业应用,但至少能做出一个教学级别项目给大家展示设计思路,保证不辜负这么多 star.
一年前看了大佬的知乎文章,开了一个仓库,本来想写着玩,结果发现还有人在用,于是断断续续把es5/6/7/8的特性都实现了,收益良多。
在里面加个window ,用window.alert(2) 没问题
interpreter.run('alert(22)')
CallExpression | @ | interpreter.js:6042 | |
---|---|---|---|
evaluate | @ | interpreter.js:6089 | |
ExpressionStatement | @ | interpreter.js:5652 | |
evaluate | @ | interpreter.js:6089 | |
Program | @ | interpreter.js:5615 | |
evaluate | @ | interpreter.js:6089 | |
run | @ | interpreter.js:255 | |
(anonymous) | @ | VM197:1 |
虽然代码,很多都是从你这里复制粘贴过去的...
但是也修复了一些bug。
目前在一个一个的语法实现,附带测试用例
最后说一下,这个仓库,真的很有学习意义,很赞。
例如运行这段代码:
function test(name){
return "hello " + name;
}
console.log(test.length); // 正常情况下,应该是1, 但实际上是0
module.exports = test;
查看了相关源码,在下面的:
Line 247 in b0f6711
FunctionExpression: (node: ESTree.FunctionExpression, scope: Scope) => {
return function (...args) {
const new_scope = new Scope('function', scope)
new_scope.invasived = true
for (let i = 0; i < node.params.length; i++) {
const { name } = <ESTree.Identifier>node.params[i]
new_scope.$const(name, args[i])
}
new_scope.$const('this', this)
new_scope.$const('arguments', arguments)
const result = evaluate(node.body, new_scope)
if (result === RETURN_SINGAL) {
return result.result
}
}
},
这里Return的function,使用的是 function (...args)
,导致它的length属性不确定..
可以这么改
FunctionExpression: (node: ESTree.FunctionExpression, scope: Scope) => {
const func function (...args) {
const new_scope = new Scope('function', scope)
new_scope.invasived = true
for (let i = 0; i < node.params.length; i++) {
const { name } = <ESTree.Identifier>node.params[i]
new_scope.$const(name, args[i])
}
new_scope.$const('this', this)
new_scope.$const('arguments', arguments)
const result = evaluate(node.body, new_scope)
if (result === RETURN_SINGAL) {
return result.result
}
}
// 手动矫正length
Object.defineProperty(func, "length", {value: node.params.length});
return func;
},
hm....
在实现async await
的时候遇到的
变量提升到底是不是个好东西
const obj = {
called: false
};
func();
function func() {
obj.called = true;
}
module.exports = obj;
上面的代码是不能解释运行的..
因为解析到func()
的时候,还没有func
这个变量
文章很精彩,忍不住也造了个轮子。
基本上看着你代码手打了一份,顺便研究了下 acorn 生成的语法书。
感觉对 js 的一些用法又多一点了解了
怎么获取返回值??
简单阅读了一下源码,感觉做了一个AST解析,然后功能类似小程序的eval。这样是否有安全问题
最近在学习作者的代码,发现22行这块是不是写错了呢?
if (this.value === 'const') {}
should be
if (this.kind === 'const') {}
Line 22 in ab7133f
Line 183 in b0f6711
这里不应该是设置父级的作用域。
应该是设置for循环里的新作用域new_scope
亲测, 下面这个例子跑不痛。
import test from "ava";
import * as fs from "fs";
import vm from "../src/vm";
test("ForInStatement-1", t => {
const sandbox: any = vm.createContext({});
const obj: any = vm.runInContext(
`
const obj = {
1: false,
2: false
};
for (let attr in obj) {
obj[attr] = true;
}
module.exports = obj;
`,
sandbox
);
t.true(obj[1]);
t.true(obj[2]);
});
attr应该是 0、1
,但实际上,永远是1,因为for循环里面的作用域没有attr变量。
只有父级作用域有attr,而且attr=1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.