在javascript环境中执行

时间:2016-01-09 22:19:56

标签: javascript coffeescript environment execution

我想允许我的用户在将某个对象应用为环境时执行一系列功能。例如,我有一些包含数据和操作的对象。

environment = {

member1 = 0

operation1 = -> 
    member1 += 1
}

我希望允许用户将命令发送到环境中,就好像它是全局对象一样,而不是使用this

引用它

environment.evaluate("operation1()")

如果我可以在环境之外创建操作,但允许将它们发送到这个假设的“评估”函数中也会很好。

有可能建立这样的东西吗?它有原生的JavaScript支持吗?

1 个答案:

答案 0 :(得分:3)

  

现在改变。刚刚意识到你需要什么

这会调用私有方法对象的成员。

// create a closure which is your environment using the module pattern
var environment = (function() {

  // local variables to the environment
  var member1 = 0;

  // public interface
  var methods = {
    operation: function(num) {
      return member1 += (num || 1);
    },
    evaluate: function evaluate(name) {
      var rest = Array.prototype.slice.call(arguments, 1);
      // call your function by name passing in the rest of the arguments
      return typeof methods[name] === 'function' && methods[name].apply(this, rest);
    }
  }

  return methods;
})();

console.assert(typeof member1 === 'undefined', 'member1 is out of scope');
console.assert((environment.evaluate("operation", 2) === 2), 'member1 === 2');
console.log(environment.evaluate("operation", 2));
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>

  

旧回答

我刚注意到你要求咖啡脚本。这是你可以使用的JavaScript。我从来没有使用过咖啡脚本,但不管怎么说,转换成咖啡和咖啡都不难写成js。

关键是围绕整个环境关闭,并使用eval修改内部状态。你最好让特定的getter和setter将api限制为你允许的东西,否则最终用户有权修改范围内的任何东西,所以没有什么是私有的。

// create a closure which is your environment using the module pattern
var environment = (function() {

  // local variables to the environment
  var member1 = 0;
 
  // return the public interface
  return {
    // this function evals the code in the context of the environment 
    evaluate: function evaluate(operation) {
      // eval a closure so anything you put in there is run and returned to the outer environment
      return eval('(function(){ return ' + operation + '})()');
    }
  }
})();

console.assert( typeof member1 === 'undefined', 'is member1 out of scope' );
console.log( environment.evaluate("++member1") );

<!-- begin snippet: js hide: false -->
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>

var es6environment = (function() {

  let member1 = 0;

  const methods = {
    operation: (num = 1) => member += num,
    evaluate: (name, ...rest) => typeof methods[name] === 'function' && methods[name].apply(this, rest);
  }

  return methods;
})();
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>