variables操作符是可能的吗?
有没有办法做到类似于以下任何一种:
var1 = 10; var2 = 20; var operator = "<"; console.log(var1 operator var2); // returns true
– 要么 –
var1 = 10; var2 = 20; var operator = "+"; total = var1 operator var2; // total === 30
不是开箱的。 但是,在包括JS在内的多种语言中手动构build起来很容易。
var operators = { '+': function(a, b) { return a + b }, '<': function(a, b) { return a < b }, // ... }; var op = '+'; alert(operators[op](10, 20));
如果你不需要的话,你可以使用ascii的名字,比如plus
,以避免经过string。 然而,有一半类似于这个问题被问到,因为有人有代表操作员的string,并要求他们的function。
你可以使用eval()
函数,但这不是一个好主意。 我认为更好的方法是为您的操作员编写函数,如下所示:
var addition = function(first, second) { return first+second; }; var subtraction = function(first, second) { return first-second; }; var operator = addition; alert(operator(12, 13)); var operator = subtraction; alert(operator(12, 13));
我相信你想要一个可变的操作符。 这里是一个,创build为对象。 您可以通过更改以下内容更改当前操作:
[yourObjectName].operation = "<" //changes operation to less than function VarOperator(op) { //you object containing your operator this.operation = op; this.evaluate = function evaluate(param1, param2) { switch(this.operation) { case "+": return param1 + param2; case "-": return param1 - param2; case "*": return param1 * param2; case "/": return param1 / param2; case "<": return param1 < param2; case ">": return param1 > param2; } } } //sample usage: var vo = new VarOperator("+"); //initial operation: addition vo.evaluate(21,5); // returns 26 vo.operation = "-" // new operation: subtraction vo.evaluate(21,5); //returns 16 vo.operation = ">" //new operation: ">" vo.evaluate(21,5); //returns true
从我最近发布的另一个答案,这是在V8,我认为JavaScriptCore,但不是Firefox,它不是规范。 既然你可以捕获操作和比较器,你可以在大多数情况下用一些工作来实现操作符本地重载。
var actions = []; var overload = { valueOf: function(){ var caller = arguments.callee.caller; actions.push({ operation: caller.name, left: caller.arguments[0] === this ? "unknown" : this, right: caller.arguments[0] }); return Object.prototype.toString.call(this); } }; overload.toString = overload.valueOf; overload == 10; overload === 10; overload * 10; 10 / overload; overload in window; -overload; +overload; overload < 5; overload > 5; [][overload]; overload == overload; console.log(actions);
输出:
[ { operation: 'EQUALS', left: overload, right: 10 }, { operation: 'MUL', left: overload, right: 10 }, { operation: 'DIV', left: 'unknown', right: overload }, { operation: 'IN', left: overload, right: DOMWindow }, { operation: 'UNARY_MINUS', left: overload, right: undefined }, { operation: 'TO_NUMBER', left: overload, right: undefined }, { operation: 'COMPARE', left: overload, right: 5 }, { operation: 'COMPARE', left: 'unknown', right: overload }, { operation: 'ToString', left: 'unknown', right: overload } ]
在这一点上,你有所有的input和操作,所以余下的部分是操作的结果。 操作的接收者将得到一个原始值,string或数字,并且你不能阻止这个。 如果它不是一个任意的接收者,说一个你已经运算符重载的类的实例,你可以处理各种get / set陷阱来拦截传入值/防止覆盖。 您可以在一些中央查找中存储操作数和操作,并使用一个简单的方法将原始值追溯到产生它的操作,然后创build您想要执行自定义操作的任何逻辑。 另一种方法是允许任意的接收器在以后可以重构成复杂的forms,将数据编码成原始值,这样它就可以被逆转回到你的复合类中。 比如说,3个不同的8位整数(255,255,255)的RGB值可以被转换为get端的单个数字,接收端可以将其转换回复杂的组件。 或者对于更复杂的数据,你甚至可以返回一个JSON序列化的string。
通过使用和谐代理(Firefox6 +,带有标志的Nodejs),使得整个过程变得非常容易,因为您可以在基本上所有内容上创build陷印代理,并从头到尾反思整个过程并执行任何您想要的操作。 您的数据/类的操作数实例,内部引擎可能访问的每个可能值的valueOf / toString / getters,您有预感知的任何接收器对象,甚至在with(trappingProxy){ "all variable lookup, creation, and setting in here invokes traps on our proxy"; }
with(trappingProxy){ "all variable lookup, creation, and setting in here invokes traps on our proxy"; }
你不能在JavaScript中重载操作符。 你可以使用function来帮助
var plus = function(a, b) { return a + b; }; var smaller = function(a, b) { return a < b; }; var operator = plus; var total = operator(a, b); operator = smaller; if(operator(var1, var2)){ /*do something*/ }
我们可以使用eval实现这个,因为我们正在使用它来进行操作符检查。
var number1 = 30; var number2 = 40; var operator = "==="; function evaluate(param1, param2, operator) { return eval(param1 + operator + param2); } if(evaluate(number1, number2, operator)) { }
这样我们就可以使用dynamic的运算符评估。