बिना किसी ऑपरेशन के जावास्क्रिप्ट सम्मेलन क्या है?


121

बिना ऑपरेशन के जावास्क्रिप्ट सम्मेलन क्या है? एक पायथन passकमांड की तरह।

  • एक विकल्प केवल एक खाली कार्य है: function() {}
  • jQuery ऑफ़र $.noop(), जो केवल ऊपर के खाली फ़ंक्शन को कॉल करता है।
  • क्या केवल एक मूल्य दर्ज करना स्वीकार्य है falseया नहीं 0?

संदर्भ में ... क्रोम में कोई त्रुटि किए बिना ये सभी कार्य:

var a = 2;
(a === 1) ? alert(1) : function() {};
(a === 1) ? alert(1) : $.noop();
(a === 1) ? alert(1) : false;
(a === 1) ? alert(1) : 0;

संपादित करें: बहुत से लोगों ने जवाब दिया, "ऐसा मत करो! कोड संरचना को बदलो!" यह मुझे एक पोस्ट की याद दिलाता है जहां किसी ने पूछा कि ब्राउज़र को कैसे सूँघना है। उन्हें पदों का एक बैराज मिला, जिसमें कहा गया था, "यह मत करो, ईवीआईएल", लेकिन किसी ने उन्हें यह नहीं बताया कि ब्राउज़र को कैसे सूँघा जाए । यह एक कोड समीक्षा नहीं है। कल्पना करें कि आप विरासत कोड के साथ काम कर रहे हैं जिसे बदला नहीं जा सकता है, और बिना किसी फ़ंक्शन के पास हुए, यह एक त्रुटि को टॉस करेगा। या, बस, यही तरीका है कि ग्राहक इसे चाहता है, और वे मुझे भुगतान कर रहे हैं । तो, सम्मान से, कृपया इस प्रश्न का उत्तर दें : जावास्क्रिप्ट में "ऑपरेशन नहीं" फ़ंक्शन को निर्दिष्ट करने का सबसे अच्छा तरीका क्या है?

EDIT2: कैसे इनमें से एक के बारे में?

true;
false;
0;
1;
null;

7
क्यों नहीं एक सरल अगर बयान?
epascarello

11
उन विकल्पों में से 0कोई भी प्रभावी रूप से किसी भी बेहतर (या बदतर) हैं। मैं कहूंगा कि सही काम करना है if (a === 1) doSomething();और इसका उपयोग ? :तब नहीं करना चाहिए जब यह समझ में न आए ।
इंगित

6
आप साइड इफेक्ट के साथ टर्नरी ऑपरेटर को गाली दे रहे हैं। अगर आपको करना है, तोif (statement) action; else ;
mplungjan

हाँ falseया 0काम करेगा; nullनो-ऑप को व्यक्त करने का एक अच्छा तरीका है।
मैट

3
मुझे आशा है कि टर्नरी की कुछ आवश्यकता है जो हम किसी कारण से नहीं देख सकते हैं ... बहुत कुछ ऐसा लगता है जैसे आप अपने कोड को शांत महसूस करने के लिए जटिल कर रहे हैं (हमने यह सब किया है!)
स्टैचू

जवाबों:


95

मूल प्रश्न, शुद्ध जावास्क्रिप्ट में एक NOOP समारोह की सबसे खूबसूरत और साफ कार्यान्वयन उत्तर देने के लिए (के रूप में भी चर्चा की है यहाँ ) है Function.prototype । यह है क्योंकि:

  1. फ़ंक्शन.प्रोटाइप एक फ़ंक्शन है:

typeof Function.prototype === "function" // returns true

  1. इसे एक फ़ंक्शन के रूप में लागू किया जा सकता है और अनिवार्य रूप से यहां दिखाए गए अनुसार कुछ भी नहीं है:
setTimeout(function() {
      console.log('Start: ', Date.now());
      Function.prototype();
      console.log('End  : ', Date.now());
    }, 1000);

हालाँकि यह एक "सच्चा noop" है क्योंकि अधिकांश ब्राउज़र इस तरह से परिभाषित noop को निष्पादित करने के लिए कुछ भी नहीं करते हैं (और इसलिए CPU चक्रों को बचाते हैं), इससे जुड़े कुछ प्रदर्शन मुद्दे हो सकते हैं (जैसा कि दूसरों द्वारा टिप्पणियों में भी उल्लेख किया गया है) अन्य उत्तर)।

हालाँकि, कहा जा रहा है, आप आसानी से अपने स्वयं के noop फ़ंक्शन को परिभाषित कर सकते हैं और, infact, कई पुस्तकालयों और चौखटे भी noop फ़ंक्शन प्रदान करते हैं। नीचे कुछ उदाहरण दिए गए हैं:

var noop = function () {};           // Define your own noop in ES3 or ES5
const noop = () => {};               // Define in ES6 as Lambda (arrow function)
setTimeout(noop, 10000);             // Using the predefined noop

setTimeout(function () {} , 10000);  // Using directly in ES3 or ES5
setTimeout(() => {} , 10000);        // Using directly in ES6 as Lambda (arrow function)

setTimeout(angular.noop, 10000);     // Using with AngularJS 1.x
setTimeout(jQuery.noop, 10000);      // Using with jQuery

यहाँ noop फ़ंक्शन (या संबंधित चर्चा या Google खोज) के विभिन्न कार्यान्वयनों की एक वर्णमाला सूची है:

AngularJS 1.x , Angular 2+ (मूल कार्यान्वयन नहीं लगता है - ऊपर दिखाए गए अनुसार खुद का उपयोग करें), Ember , jQuery , Lodash , NodeJS , Ramda , React (एक मूल कार्यान्वयन नहीं लगता है) - अपने स्वयं के उपयोग करें जैसा कि ऊपर दिखाया गया है), RxJS , अंडरस्कोर

बॉटम लाइन : हालांकि फंक्शन.प्रोटोटाइप जावास्क्रिप्ट में एक नॉओप को व्यक्त करने का एक सुंदर तरीका है, हालांकि, इसके उपयोग से संबंधित कुछ प्रदर्शन मुद्दे हो सकते हैं। तो, आप अपने स्वयं के (जैसा कि ऊपर दिखाया गया है) परिभाषित और उपयोग कर सकते हैं या पुस्तकालय / रूपरेखा द्वारा परिभाषित एक का उपयोग कर सकते हैं जिसे आप अपने कोड में उपयोग कर रहे हैं।


5
इसका उत्तर होना चाहिए। Function.prototype()यदि आपको टाइमआउट की आवश्यकता नहीं है, तो आप इसका उपयोग भी कर सकते हैं और चाहते हैं कि इसे तुरंत निष्पादित किया जाए।
स्प्रिंगलोडेड

1
setTimeout(Function(), 10000);
यानी

@iegik: +1 हाँ आप सही हैं। निम्नलिखित में से सभी समान हैं: सेटटाइमआउट (फ़ंक्शन () {}, 10000); या सेटटाइमआउट (नया फ़ंक्शन (), 10000); या सेटटाइमआउट (फ़ंक्शन (), 10000); या सेटटाइमआउट (फ़ंक्शन, 10000); जावास्क्रिप्ट व्याकरण और फंक्शन कन्स्ट्रक्टर कार्यान्वयन के बाद से इन निर्माणों की अनुमति मिलती है।
एलन सीएस

5
ईएस 6 में या बैबिल या किसी अन्य ट्रांसपिलर का (( )=>{};)तकनीकी रूप से शुद्ध जेएस का उपयोग करके और function () {}बिल्कुल बराबर के बराबर।
रे फॉस

2
मुझे अपने कार्यक्रम में डिबग कोड को कुशलतापूर्वक बंद करने के लिए एक नो-ऑप जैसे निर्माण को खोजने में दिलचस्पी थी। C / C ++ में, मैंने मैक्रोज़ का उपयोग किया होगा। मैंने अपने fn को Function.prototype को असाइन करने का परीक्षण किया और इसे समय पर वापस करने के लिए फ़ंक्शन के अंदर केवल एक स्टेटमेंट होने के परिणामों की तुलना करते हुए, इसे समयबद्ध किया। मैंने इनकी तुलना केवल लूप से कार्य को पूरी तरह से हटाने के परिणामों से की। दुर्भाग्य से, फंक्शन.प्रोटोटाइप ने बिल्कुल अच्छा प्रदर्शन नहीं किया। एक खाली फ़ंक्शन को कॉल करना प्रदर्शन में बहुत बेहतर था, यहां तक ​​कि फ़ंक्शन को कॉल करने की तुलना में अधिक सरल है अगर 'वापसी के लिए अंदर' परीक्षण।
15

72

सबसे संक्षिप्त और performant NOOP एक है खाली तीर समारोह : ()=>{}

एरो फ़ंक्शंस IE को छोड़कर सभी ब्राउज़रों में मूल रूप से काम करते हैं ( यदि आपको आवश्यक हो तो एक बेबल ट्रांसफ़ॉर्म है ): MDN


()=>{} बनाम Function.Prototype

  • ()=>{}है 87% तेजी से Function.prototypeक्रोम 67 में।
  • ()=>{}है 25% तेजी से Function.prototypeफ़ायरफ़ॉक्स 60 में।
  • ()=>{}है 85% तेजी से Function.prototypeएज में (2018/06/15)
  • ()=>{}की तुलना में 65% कम कोड है Function.prototype

नीचे दिया गया परीक्षण तीर फ़ंक्शन का उपयोग करके पूर्वाग्रह देने के लिए गर्म करता है Function.prototype, फिर भी तीर फ़ंक्शन स्पष्ट विजेता है:

const noop = ()=>{};
const noopProto = Function.prototype;

function test (_noop, iterations) {
    const before = performance.now();
    for(let i = 0; i < iterations; i++) _noop();
    const after = performance.now();
    const elapsed = after - before;
    console.info(`${elapsed.toFixed(4)}MS\t${_noop.toString().replace('\n', '')}\tISNOOP? ${_noop() === undefined}`);
    return elapsed;
}

const iterations = 10000000
console.info(`noop time for ${iterations.toLocaleString()} iterations`)
const timings = {
    noop: test(noop, iterations),
    noopProto: test(noopProto, iterations)
}

const percentFaster = ((timings.noopProto - timings.noop)/timings.noopProto).toLocaleString("en-us", { style: "percent" });
console.info(`()=>{} is ${percentFaster} faster than Function.prototype in the current browser!`)


1
मैंने कुछ विकल्पों की तुलना करने के लिए एक jsPerf परीक्षण बनाया: noop-function । ऐसा लगता है कि फ़ायरफ़ॉक्स 54 में, सभी विकल्प समकक्ष के बारे में प्रतीत होते हैं; क्रोमियम 58 में, Function.prototypeकाफी धीमी है, लेकिन अन्य विकल्पों में से कोई भी एक निश्चित लाभ नहीं है।
लुकास विर्कमिस्टर

_=>{}एक चरित्र कम है और एक ही काम करता है।
रॉस एट्रिल

@RossAttrill * समान चीज़ - _=>{}का एक ही पैरामीटर है। यदि कोई TypeScript का उपयोग एक बहुत ही सख्त कॉन्फ़िगरेशन के साथ कर रहा है, तो वह संकलन नहीं करेगा। यदि आप इसे कहते हैं, तो आपका आईडीई आपको यह बताएगा कि यह एकल पैरामीटर को स्वीकार करता है जो किसी भी प्रकार का हो सकता है (दोनों जावास्क्रिप्ट और विशेष रूप से टाइपकोड बनाम vscode में)।
cchamberlain

15

आप यहां जो भी हासिल करते हैं वह गलत है। केवल अभिव्यक्ति में पूर्ण विवरण के रूप में तिर्यक अभिव्यक्तियों का उपयोग नहीं किया जाएगा, इसलिए आपके प्रश्न का उत्तर है:

आपके सुझावों में से कोई नहीं, इसके बजाय करें:

var a = 2;
if (a === 1)
    alert(1)
// else do nothing!

तब कोड आसानी से समझ में आता है, पठनीय और जितना संभव हो उतना कुशल है।

जब यह सरल हो सकता है, तो इसे और अधिक कठिन क्यों बनाएं?

संपादित करें:

तो, क्या एक "नो-ऑपरेशन" कमांड मूल रूप से एक अवर कोड संरचना को इंगित करता है?

आपको मेरी बात याद आ रही है। उपरोक्त सभी टर्नरी अभिव्यक्ति के बारे में है x ? y : z

लेकिन, कोई भी ऑपरेशन कमांड उच्च स्तरीय भाषाओं जैसे कि जावास्क्रिप्ट में कोई अर्थ नहीं रखता है।

इसका उपयोग आमतौर पर निचले स्तर की भाषाओं में किया जाता है, जैसे कि असेंबली या सी, प्रोसेसर बनाने के तरीके के रूप में समय के प्रयोजनों के लिए एक निर्देश के लिए कुछ भी नहीं करते हैं।

जे एस में, आप क्या करना है कि क्या 0;, null;, function () {};या एक खाली बयान, वहाँ महान संभावना है कि यह interpretor द्वारा नजरअंदाज कर दिया जाएगा जब यह पढ़ रही है रहे हैं, लेकिन इससे पहले कि यह व्याख्या हो जाता है, तो अंत में, तुम सिर्फ अपने कार्यक्रम होना बनाती हूँ वास्तव में समय की एक छोटी राशि से अधिक धीरे-धीरे लोड। नोटा नेने : मैं यह मान रहा हूं, क्योंकि मैं किसी भी व्यापक रूप से इस्तेमाल किए जाने वाले जेएस दुभाषिया में शामिल नहीं हूं, और संभावना है कि प्रत्येक दुभाषिया की अपनी रणनीति है।

यदि आप किसी चीज़ का उपयोग कुछ अधिक जटिल, जैसे $.noop()या var foo = function () {}; foo()फिर करते हैं, तो दुभाषिया एक अप्रयुक्त फ़ंक्शन कॉल कर सकता है जो आपके फ़ंक्शन स्टैक के कुछ बाइट्स और कुछ चक्रों को खराब कर देगा।

एकमात्र कारण जो मैं देख रहा हूँ जैसे कि कोई फ़ंक्शन $.noop()मौजूद होगा, फिर भी कुछ ईवेंट फ़ंक्शन को कॉलबैक फ़ंक्शन देने में सक्षम होगा जो अपवाद को फेंक देगा यदि वह कॉलबैक नहीं कह सकता। लेकिन फिर, यह आवश्यक रूप से एक फ़ंक्शन है जिसे आपको देने की आवश्यकता है, और इसे noopनाम देना एक अच्छा विचार है इसलिए आप अपने पाठकों को बता रहे हैं (और यह 6 महीने में हो सकता है) कि आप जानबूझकर एक खाली फ़ंक्शन दे सकते हैं।

अंत में, "अवर" या "श्रेष्ठ" कोड संरचना जैसी कोई चीज नहीं है। आप अपने उपकरणों का उपयोग करने के तरीके में या तो सही या गलत हैं .. अपने उदाहरण के लिए एक टर्नरी का उपयोग करना एक हथौड़ा का उपयोग करने के समान है जब आप पेंच करना चाहते हैं। यह काम करेगा, लेकिन आपको यकीन नहीं है कि आप उस पेंच पर कुछ लटका सकते हैं।

जिसे "हीन" या "श्रेष्ठ" माना जा सकता है वह है आपके कोड में डाला गया एल्गोरिथम और विचार। लेकिन यह दूसरी बात है।


1
तो, क्या एक "नो-ऑपरेशन" कमांड मूल रूप से एक अवर कोड संरचना को इंगित करता है?
किमीिक्लस

3
@kmiklas: मैं यह नहीं कह सकता कि मैंने कभी भी NOOP के लिए एक वैध आवश्यकता को पाया है, कोडांतरक के बाहर।
मैट बर्लेंड

@ ज़मो: मुझे आपकी बात समझ में आती है कि आपकी टिप्पणी किस तरह से तीखी अभिव्यक्ति से संबंधित है; सभी को मेरी बात याद आती है कि यह "नो ऑपरेशन" फ़ंक्शन के लिए कॉल का एक उदाहरण मात्र था।
kmiklas

1
बेशक, नो-ऑप फीचर को चाहने / चाहने के कारण हैं। किसी चीज़ पर अपने 12 सेकंड के गहन विचार के आधार पर व्यापक सामान्यीकरण न करें। जावास्क्रिप्ट एक भाषा है जो कार्यों को चर के रूप में पूरी तरह से नियंत्रणीय बनाती है। मान लीजिए कि आपको एक स्पष्ट परीक्षण के बिना किसी फ़ंक्शन को अक्षम करना है? यह उसके लिए एकदम सही होगा। यदि आपके पास एक फ़ंक्शन है जो अक्सर दिखाई देता है, जैसे कि डिबग स्टेटमेंट, तो यह अच्छा होगा कि फ़ंक्शन को हर बार फ़ंक्शन को देखने के लिए कुछ चर का परीक्षण करने के लिए अतिरिक्त कोड जोड़ने के बजाय फ़ंक्शन को पुन: असाइन करके इसे स्विच करने में सक्षम होना चाहिए। ।
बेवरिन

2
@bearvarine आपको मेरे द्वारा दिए जा रहे उच्च विचार के लिए धन्यवाद: -D आप अपनी टिप्पणी में बिल्कुल सही हैं, लेकिन यह वास्तव में कोड डिजाइन के लिए नहीं है, बस एक हैक का उपयोग करके डिजाइन का मखौल उड़ाना है। आप जो वर्णन करते हैं उसे बन्दर पैचिंग भी कहा जाता है, और इसका एक कारण है ;-)
zmo

7

मुझे लगता है कि jQuery noop()का इरादा कोड को उपलब्ध नहीं होने पर डिफ़ॉल्ट फ़ंक्शन प्रदान करके कोड को दुर्घटनाग्रस्त होने से रोकना है। उदाहरण के लिए, निम्नलिखित कोड नमूने पर विचार करते हुए, $.noopअगर fakeFunctionपरिभाषित नहीं किया जाता है, तो अगली कॉल को fnदुर्घटनाग्रस्त होने से बचाया जाता है:

var fn = fakeFunction || $.noop;
fn() // no crash

फिर, noop()अपने कोड में हर जगह एक ही खाली फ़ंक्शन को लिखने से बचने के द्वारा मेमोरी को बचाने की अनुमति देता है। वैसे, (टोकन प्रति 6 बाइट्स सहेजे गए) की $.noopतुलना में थोड़ा कम है function(){}। तो, आपके कोड और खाली फ़ंक्शन पैटर्न के बीच कोई संबंध नहीं है। उपयोग करें null, falseया 0यदि आप चाहें, तो आपके मामले में कोई दुष्प्रभाव नहीं होगा। इसके अलावा, यह ध्यान देने योग्य है कि यह कोड ...

true/false ? alert('boo') : function(){};

... पूरी तरह से बेकार है क्योंकि आप कभी भी फ़ंक्शन को कॉल नहीं करेंगे, और यह एक ...

true/false ? alert('boo') : $.noop();

... और भी बेकार है क्योंकि आप एक खाली फ़ंक्शन को कॉल करते हैं, जो बिल्कुल वैसा ही है ...

true/false ? alert('boo') : undefined;

आइए ifयह बताने के लिए कि यह कितना बेकार है , तिर्यक अभिव्यक्ति को प्रतिस्थापित करें :

if (true/false) {
    alert('boo');
} else {
    $.noop(); // returns undefined which goes nowhere
}

आप बस लिख सकते हैं:

if (true/false) alert('boo');

या इससे भी कम:

true/false && alert('boo');

अंत में आपके प्रश्न का उत्तर देने के लिए, मुझे लगता है कि "एक पारंपरिक ऑपरेशन नहीं" वह है जो कभी नहीं लिखा जाता है।


1
हालांकि कभी-कभी आपको एक फ़ंक्शन प्रदान करना होगा। उदाहरण के लिए वादों के साथ तब (fn, fn) कभी-कभी आप दूसरा फ़ंक्शन प्रदान करना चाहते हैं लेकिन पहला फ़ंक्शन नहीं। इसलिए आपको एक स्थान धारक के लिए कुछ चाहिए ...mypromise.then($.noop, myErrorhandler);
जॉन हेनकेल

3

मैं उपयोग करता हूं:

 (0); // nop

इस रन के निष्पादन समय का परीक्षण करने के लिए:

console.time("mark");
(0); // nop
console.timeEnd("mark");

परिणाम: निशान: 0.000ms

का उपयोग करके Boolean( 10 > 9)इसे कम किया जा सकता है ( 10 > 9)जो केवल रिटर्न के लिए है true। एक एकल ऑपरेंड का उपयोग करने के विचार के साथ आ रहा हूं जिसकी मुझे पूरी उम्मीद थी(0); करूंगा कि वह वापस आ जाएगा false, लेकिन यह केवल तर्क को वापस लौटाता है जैसा कि कंसोल पर इस परीक्षण का प्रदर्शन करके समीक्षा की जा सकती है।

> var a = (0);
< undefined
> a
< 0

1
इस प्रयास के कई लोग मिलेंगेargument 0 is not a function
कोड व्हिस्परर

4
आप बस 0. असाइन कर रहे हैं। IMO noopएक फ़ंक्शन होना चाहिए जो undefinedपरिणाम के साथ मूल्यांकन करता है ।
cchamberlain

1
यह कथन (0) कैसा है; 0 ?, को प्रदान करना जहां var और बराबर चिन्ह है? (0) के सामने कोई फ़ंक्शन नाम नहीं है, इसलिए मैं नहीं देखता कि यह एक तर्क कैसे हो सकता है? यदि आप टाइपोफ ((0)) की कोशिश करते हैं, तो यह एक संख्या के रूप में वापस आता है। जब मैं प्रश्न का उत्तर देता हूं, तो मैं एक बयान दे रहा था, जिसका उपयोग मैं एक एनओपी की नकल करने के लिए करता हूं, लेकिन मैं केवल उपयोग करने के लिए अपने उत्तर को बदलने के लिए तैयार हूं; एक खाली बयान का प्रतिनिधित्व करने के लिए
अंडे

1
मुझे लगता है (0); ओपी के सवाल का एक स्वीकार्य समाधान है। मुझे लगता है कि लोग भ्रमित हो रहे हैं क्योंकि उन्होंने इस पृष्ठ को एक फ़ंक्शन की तलाश में पाया था जो एक बयान की बजाय कुछ भी नहीं करता है। ओपी शुरू function(){}में समाधान के रूप में सुझाव देकर मदद नहीं कर रहा है । कॉलिंग (0)()का कारण होगाTypeError: 0 is not a function
बेंजामिन

मैं जिक्र कर रहा था var a = (0);। एक नो-ऑप मेमोरी को नहीं बदलना चाहिए और आपका असाइनमेंट उदाहरण बस यही करता है। (0)अपने आप ही एक बेकार नहीं सेशन माना जा सकता है (वहाँ जावास्क्रिप्ट में इनमें से एक अनंत संख्या रहे हैं तो कुछ भी नहीं है कि आपके उदाहरण यहां विशेष बनाता है)।
cchamberlain

2

Function.prototypeओवर का उपयोग करने में कोई समस्या या प्रदर्शन जुर्माना नहीं है() => {}

Function.prototypeहर बार एक नए अनाम फ़ंक्शन को फिर से परिभाषित करने के बजाय एक सिंगलटन फ़ंक्शन का मुख्य लाभ होता है। यह विशेष रूप से महत्वपूर्ण है जैसे कि नो-ऑप का उपयोग करेंFunction.prototypeडिफ़ॉल्ट मानों को परिभाषित करने और इसे याद क्योंकि यह आपको एक सुसंगत ऑब्जेक्ट पॉइंटर देता है जो कभी नहीं बदलता है।

मैं इसके Function.prototypeबजाय सिफारिश कर रहा हूं Functionक्योंकि वे समान नहीं हैं:

Function() === Function()
// false

Function.prototype() === Function.prototype()
// true

इसके अलावा, अन्य उत्तरों के बेंचमार्क भ्रामक हैं । वास्तव में, की Function.prototypeतुलना में तेजी से प्रदर्शन करता है() => {} आप जो लिखते हैं और बेंचमार्क चलाते हैं, उसके आधार पर :

आप जेएस बेंचमार्क पर भरोसा नहीं कर सकते << इस प्रश्न पर विशेष रूप से बेंचमार्क को बाहर करना।

बेंचमार्क से अपने कोड को स्टाइल न करें; जो कुछ भी करने योग्य है उसे करें और दुभाषिया को यह पता लगाने दें कि लंबे समय में कैसे अनुकूलित किया जाए।

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