From 53f360650316cfbdeda5235ce5358f0d5990465f Mon Sep 17 00:00:00 2001 From: bplok20010 <505931977@qq.com> Date: Wed, 11 Mar 2020 10:24:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 46 ++++++++++++++++++++++++++++++++++++----- src/interpreter/main.ts | 15 ++++++++++---- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 79bfcf4..1e08844 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ 基于 JavaScript 编写的 JavaScript 解释器;A JavaScript interpreter, written completely in JavaScript; -支持es5语法 +支持 es5 语法 > 解决在不支持`eval`或`Function`的执行环境下执行 JavaScript 代码。例如:微信小程序 [示例](https://github.com/bplok20010/eval5-wx-demo)。 @@ -20,13 +20,13 @@ import { evaluate, Function, vm, Interpreter } from "eval5"; // 设置默认作用域 Interpreter.global = window; -//或 evaluate("1+1", Object.create(window)); evaluate("1+1", window); // 2 const func = new Function("a", "b", "return a+b;"); console.log(func(1, 1)); // 2 +const ctx = window; const interpreter = new Interpreter(ctx, { timeout: 1000, }); @@ -56,6 +56,8 @@ VERSION 例如: ```javascript +import { Interpreter } from "eval5"; + Interpreter.global = window; ``` @@ -68,6 +70,8 @@ Interpreter.global = window; > 如果执行环境支持 eval 函数建议使用原生的 eval,除非 eval 需要使用局部变量时,如下情况: ```javascript +import { Interpreter } from "eval5"; + const ctx = Object.create(window); ctx.eval = Interpreter.eval; @@ -118,11 +122,13 @@ for(let i = 0; i < 10; i++) { **原因在于解释器会忽略`const` `let`类型,都当作`var`处理。** -### `constructor`(ctx: {}, options?: { timeout?: number}) +### `constructor`(ctx: {} = Interpreter.global, options?: { timeout?: number}) 构造函数 ```javascript +import { Interpreter } from "eval5"; + var interpreter = new Interpreter(window); ``` @@ -131,6 +137,8 @@ var interpreter = new Interpreter(window); 返回脚本中执行的最后一个表达式结果 ```javascript +import { Interpreter } from "eval5"; + var interpreter = new Interpreter(window); interpreter.evaluate("alert(1+1)"); ``` @@ -150,14 +158,16 @@ interpreter.evaluate("alert(1+1)"); 执行给定的字符串脚本,返回脚本中执行的最后一个表达式结果 ```javascript +import { evaluate } from "eval5"; + evaluate("console.log(1+1)", { console: console }); ``` ## Function -同 js 原生的 Function - ```javascript +import { Function } from "eval5"; + const func = new Function("a", "b", "return a+b;"); console.log(func(1, 2)); ``` @@ -174,6 +184,32 @@ console.log(func(1, 2)); - vm.runInNewContext - vm.Script +## Tips + +`eval5`不支持`use strict`模式,但在函数的调用中`this`默认值是`undefined`,可通过设置`Interpreter.rootContext`来设置`this`的默认值,如: + +``` +const code = ` +function test(){ + return this;// undefined +} +test(); +` +evaluate(code) +``` + +``` +Interpreter.rootContext = 1; + +const code = `function test(){ + return this;// 1 +} +test(); +` +evaluate(code) + +``` + ## License MIT diff --git a/src/interpreter/main.ts b/src/interpreter/main.ts index 0bdbad3..9fb62e8 100644 --- a/src/interpreter/main.ts +++ b/src/interpreter/main.ts @@ -198,7 +198,7 @@ export class Interpreter { static readonly Function = IFunction; static ecmaVersion: ECMA_VERSION = 5; // alert.call(rootContext, 1); - // But alert({}, 1); // Illegal invocation + // fix: alert.call({}, 1); // Illegal invocation static rootContext = void 0; static global = Object.create(null); @@ -870,10 +870,16 @@ export class Interpreter { } // method call + // eg:obj.say(...) + // eg: obj.say.call(...) + // eg: obj.say.apply(...) + // ====================== + // obj.func(...) + // func = func.bind(obj) // tips: - // test.call(ctx, ...) === test.call.bind(test)(ctx, ...) - // test.apply(ctx, ...) === test.apply.bind(test)(ctx, ...) - // test.f(...) === test.f.bind(test)(...) + // func(...) -> func.bind(obj)(...) + // func.call(...) -> obj.func.call.bind(obj.func)(...) + // func.apply(...) -> obj.func.apply.bind(obj.func)(...) // ...others return func.bind(obj); }; @@ -912,6 +918,7 @@ export class Interpreter { // this = undefined // tips: // test(...) === test.call(undefined, ...) + // fix: alert.call({}, ...) Illegal invocation return func.bind(Interpreter.rootContext); }; }