2016-01-09 78 views
0

我想允許我的用戶在應用某個對象作爲環境時執行一系列的功能。例如,我有一些包含數據和操作的對象。在javascript環境中執行

environment = { 

member1 = 0 

operation1 = -> 
    member1 += 1 
} 

我想允許用戶發送命令到環境中,就好像它是全局對象,而不this

引用它即

environment.evaluate("operation1()") 

這也將是如果不錯我可以在環境之外創建操作,但允許將它們發送到這個假設的「評估」功能中。

是否有可能構建這樣的東西?它有本機JavaScript支持嗎?

回答

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>