我想允许我的用户在将某个对象应用为环境时执行一系列功能。例如,我有一些包含数据和操作的对象。
environment = {
member1 = 0
operation1 = ->
member1 += 1
}
我希望允许用户将命令发送到环境中,就好像它是全局对象一样,而不是使用this
即
environment.evaluate("operation1()")
如果我可以在环境之外创建操作,但允许将它们发送到这个假设的“评估”函数中也会很好。
有可能建立这样的东西吗?它有原生的JavaScript支持吗?
答案 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>