क्या परिवर्तनीय संचालक संभव हैं?


89

क्या निम्नलिखित में से किसी के समान कुछ करने का एक तरीका है:

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

जवाबों:


173

बॉक्स से बाहर नहीं। हालाँकि, JS सहित कई भाषाओं में इसका निर्माण आसान है।

var operators = {
    '+': function(a, b) { return a + b },
    '<': function(a, b) { return a < b },
     // ...
};

var op = '+';
alert(operators[op](10, 20));

plusयदि आप की जरूरत नहीं है, तो आप स्ट्रिंग के माध्यम से जाने से बचने के लिए, असि-आधारित नामों का उपयोग कर सकते हैं । हालाँकि, इसमें से आधे सवाल एक जैसे थे क्योंकि किसी के पास ऑपरेटरों का प्रतिनिधित्व करने वाले तार थे और उनसे कार्य चाहते थे।


6

मेरा मानना ​​है कि आप एक परिवर्तनीय ऑपरेटर चाहते हैं। यहाँ एक, वस्तु के रूप में बनाया गया है। आप वर्तमान ऑपरेशन को बदलकर बदल सकते हैं:

[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

6

आप 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));

6

हम इसे इवल का उपयोग करके लागू कर सकते हैं, क्योंकि हम इसे ऑपरेटर की जाँच के लिए उपयोग कर रहे हैं।

var number1 = 30;
var number2 = 40;
var operator = "===";

function evaluate(param1, param2, operator) {
     return eval(param1 + operator + param2);
}

if(evaluate(number1, number2, operator)) {
}

इस तरह हम डायनेमिक ऑपरेटर मूल्यांकन का उपयोग कर सकते हैं।


3

एक अन्य उत्तर से जो मैंने हाल ही में पोस्ट किया है, यह V8 में है और मुझे लगता है कि JavaScriptCore, लेकिन फ़ायरफ़ॉक्स नहीं है और यह कल्पना नहीं है। चूंकि आप ऑपरेशन को रोक सकते हैं और तुलनित्रों को आप थोड़े से काम के साथ अधिकांश स्थितियों में ऑपरेटर देशी ओवरलोडिंग को लागू कर सकते हैं।

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 } ]

इस बिंदु पर आपके पास सभी इनपुट और ऑपरेशन हैं इसलिए शेष भाग ऑपरेशन का परिणाम है। ऑपरेशन के रिसीवर को एक आदिम मूल्य मिलेगा, या तो स्ट्रिंग या संख्या, और आप इसे रोक नहीं सकते हैं। यदि यह एक मनमानी करने वाला नहीं है, तो कहें कि आपके द्वारा ओवरलोड किए गए वर्ग का एक उदाहरण, आप आने वाले मूल्य को रोकने / ओवरराइटिंग को रोकने के लिए विभिन्न प्राप्त / सेट ट्रैप को संभाल सकते हैं। आप कुछ केंद्रीय लुकअप में ऑपरेंड्स और ऑपरेशन को स्टोर कर सकते हैं और उस प्राइमरी वैल्यू का पता लगाने के लिए एक सरल विधि का उपयोग कर सकते हैं जो उस ऑपरेशन को वापस करता है जो इसे निर्मित करता है, और फिर जो भी तर्क आप अपने कस्टम ऑपरेशन को करना चाहते हैं उसे बनाएं। एक और तरीका जो मनमाने ढंग से रिसीवर को अनुमति देगा, जिसे बाद में जटिल रूपों में पुनर्गठित किया जा सकता है, यह डेटा को आदिम मूल्य में एन्कोडिंग में होगा ताकि इसे आपके जटिल वर्ग में वापस उलटा किया जा सके। जैसे 3 अलग 8 बिट पूर्णांक (255,255,255) के RGB मान को गेट एंड पर एकल नंबर में बदला जा सकता है और रिसीवर का अंत तुच्छ रूप से इसे अपने जटिल घटकों में परिवर्तित कर सकता है। या अधिक जटिल डेटा के लिए आप JSON क्रमांकित स्ट्रिंग भी लौटा सकते हैं।

हार्मनी प्रॉक्सि (फ़ायरफ़ॉक्स 6 +, फ्लैग के साथ नोड्स) तक पहुंच होने से यह पूरी प्रक्रिया बेहद आसान हो जाती है, क्योंकि आप मूल रूप से सब कुछ पर जाल बना सकते हैं और अंत से अंत तक पूरी प्रक्रिया को आत्मसात कर सकते हैं और जो चाहें कर सकते हैं। आपके डेटा / वर्ग के ऑपरेंड इंस्टेंस, वैल्यूऑफ / स्ट्रोइंग / प्राप्त करने वाले हर संभव मूल्य के आंतरिक इंजन तक पहुंच सकते हैं, किसी भी रिसीवर वस्तु जिसे आप के बारे में पूर्व-जागरूकता है, और यहां तक ​​कि मामले के मामले में मनमाना रिसीवर भी फंस सकते हैंwith(trappingProxy){ "all variable lookup, creation, and setting in here invokes traps on our proxy"; }


2

आप ऑपरेटरों को जावास्क्रिप्ट में अधिभार नहीं दे सकते। आप मदद करने के लिए बेशक उपयोग कार्यों को बंद कर सकते हैं

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*/ }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.