Javascript动态执行代码有new Function
方法和eval
方法。
new Function
其中Function构造器生成的函数,是在全局作用域中被创建。
请看nodejs环境下的Demo:
global.n = 1;
function f(){
var n = 2;
var e = new Function("return n;");
return e;
}
function f2(){
var n = 2;
function e(){
return n;
}
return e;
}
console.log(f()()); // 1
console.log(f2()()); // 2
eval
eval函数的执行过程:
1.建立一个新的执行环境。
3.执行环境中的this指向当前执行环境的this。
3.执行环境中的作用域链指向当前执行环境的作用域链。
4.正常执行代码。
请看nodejs环境下的Demo:
global.n = 1;
function f2(){
var n = 2;
function e(){
return n;
}
return e;
}
var evaluedFn = eval("("+f2.toString()+")");
var nativeFn = evaluedFn();
console.log(nativeFn()); // 2
实现需求的手法顺序
函数>动态逻辑加载>DSL
垠老师的DSL使用指导原则:
- 尽一切可能避免创造 DSL,因为它会带来严重的理解,交流和学习曲线问题,可能会严重的降低团队的工作效率。如果这个 DSL 是给用户使用,会严重影响用户体验,降低产品的可用性。
- 大部分 DSL 要解决的问题,不过是“动态逻辑加载”。为了这个目的,你完全可以利用已有的语言(比如 JavaScript),或者取其中一部分构造,通过动态调用它的解释器(编译器)来达到这个目的,而不需要创造新的 DSL。
- 大部分时候写库代码,把需要的功能做成函数,其实就可以解决问题。
- 如果真的到了必须创造 DSL 的时候,非 DSL 不能解决问题,才可以动手设计 DSL。但 DSL 必须由程序语言专家来完成,否则它还是可能给产品和团队带来严重的后果。
参考:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval
https://www.zhihu.com/question/68213498
http://www.yinwang.org/blog-cn/2017/05/25/dsl