临时全局变量/函数和原型覆盖来编写JS DSL

时间:2012-10-31 01:48:52

标签: javascript node.js global-variables dsl prototype-programming

我正在探索我正在研究的JavaScript路由框架的各种选项,并且我想提供用JavaScript编写的用于定义路由器的DSL。

我有想法在String类上使用临时原型覆盖(维护先前原型值的哈希值,覆盖,运行DSL代码,将原型值重置为它们的原样),以达到这样的目的:< / p>

DSL.run(function() {
  "hello".isSomething();
  "foo".isSomethingElse();
});

另一个想法是使用define临时全局变量,然后在DSL完成运行后删除/重置它们。这样,如果您使用window(或任何全局对象)作为this上下文运行DSL闭包,我相信您应该能够执行以下操作:

DSL.run(function() {
  defineSomething("hello");
  defineSomethingElse("foo");
});

我知道我知道我知道我应该非常小心原型重载和污染全局命名空间,但这似乎是一种非常本地化且易于清理的方法来防止这种事情发生。我的问题是,是否还有其他考虑因素可以阻止这种现象成为现实?

我能想到的一个潜在问题是,这是否可以在Node.js设置中工作,其中代码存储在单独的模块中,而全局变量彼此保持不变,我认为这将消除选项B,但是关于String原型呢重载?这些是模块之间共享的,对吧?例如如果我包含设置String原型值的模块A,这些原型值将在包含代码中可用,对吧?

另外,如果有人以前做过这种事,请告诉我。我认为这是解决这类问题的一种聪明的方法,我没有看到任何类似的东西,但我想确保我不会遗漏一些非常明显和诅咒的东西。

1 个答案:

答案 0 :(得分:1)

使用delete String.prototype[method]

var dsl = function(f){
  var _ = String.prototype;
  _.isSomething = function(){
    console.log('isSomething: '+this);
  }
  _.isSomethingElse = function(){
    console.log('isSomethingElse: '+this);
  }

  f();

  delete _.isSomething;
  delete _.isSomethingElse;
}

dsl(function(){
  "hello".isSomething(); // isSomething: hello
  "foo".isSomethingElse(); // isSomethingElse: foo
});

// "hello".isSomething(); // error "Object has no method 'isSomething'"
// "foo".isSomethingElse(); // error "Object has no method 'isSomethingElse'"