जावास्क्रिप्ट की छिपी विशेषताएं? [बन्द है]


312

जावास्क्रिप्ट की "छिपी हुई विशेषताएं" क्या आपको लगता है कि हर प्रोग्रामर को पता होना चाहिए?

निम्नलिखित प्रश्नों के उत्तर की उत्कृष्ट गुणवत्ता को देखने के बाद मुझे लगा कि यह जावास्क्रिप्ट के लिए पूछने का समय है।

भले ही जावास्क्रिप्ट यकीनन सबसे महत्वपूर्ण क्लाइंट साइड भाषा है (बस Google से पूछें) यह आश्चर्य की बात है कि अधिकांश वेब डेवलपर्स यह सराहना करते हैं कि यह वास्तव में कितना शक्तिशाली है।


1
क्या आपका मतलब यह नहीं था कि "इस प्रतिनिधि को देखा। अंक और विचार इस अन्य प्रश्न को आकर्षित करते हैं, मैंने सोचा कि मैं अपने प्रश्न को बढ़ाने के लिए लगभग एक ही सवाल पूछूंगा"? ;-)
बॉबी जैक

1
ज़रूर, निराशावादी। :) मैंने इसे एक सामुदायिक प्रश्न बनाने पर विचार किया। इसके बाद, जब आप एक निश्चित संख्या में अंक प्राप्त करते हैं, तो यह सभी कम रिटर्न होता है।
एलन लालडेन्

1
पर्याप्त रूप से उचित - ऐसा नहीं लगता है जैसे कि आपको रेप की आवश्यकता है! मुझे लगता है कि मेरे पास सी # एक के साथ एक बड़ा मुद्दा है - मुझे बिल्कुल उस प्रकार का प्रश्न नहीं लगता है जिसके लिए इस साइट का उद्देश्य था।
बॉबी जैक

3
हाँ, शायद नहीं, लेकिन मुझे ज्ञान उत्तर में बहुत अच्छा लगा। मुझे लगता है कि यदि आप एसओ के लिए नहीं हैं तो एक जगह पर एक औसत सी # प्रोग्रामर को उजागर करने के लिए आपको मुश्किल से दबाया जाएगा। इसके साथ खेलने में बरसों लगेंगे, वही मुश्किल जीत लिस्ट के साथ आएगा।
एलन लालोंडे

7
मैं अब 10 साल से पेशेवर रूप से जावास्क्रिप्ट लिख रहा हूं और मैंने इस धागे से एक या तीन चीजें सीखी हैं। धन्यवाद, एलन!
एंड्रयू हेजेज ने

जवाबों:


373

किसी फ़ंक्शन के लिए आपको किसी भी पैरामीटर को परिभाषित करने की आवश्यकता नहीं है। आप बस फ़ंक्शन की argumentsसरणी जैसी ऑब्जेक्ट का उपयोग कर सकते हैं ।

function sum() {
    var retval = 0;
    for (var i = 0, len = arguments.length; i < len; ++i) {
        retval += arguments[i];
    }
    return retval;
}

sum(1, 2, 3) // returns 6

117
हालांकि यह देखते हुए कि तर्क एक सरणी की तरह काम करता है, यह एक वास्तविक जावास्क्रिप्ट ऐरे नहीं है - यह सिर्फ एक वस्तु है। तो आप शामिल नहीं कर सकते (), पॉप (), धक्का (), टुकड़ा () और इसके बाद। (यदि आप चाहें तो आप इसे एक वास्तविक सरणी में बदल सकते हैं: "var argArray = Array.prototype.slice.call (तर्क);")
याकूब मैटिसन

51
यह भी ध्यान देने योग्य है कि आर्ग्यूमेंट ऑब्जेक्ट को एक्सेस करना अपेक्षाकृत महंगा है - सबसे अच्छा उदाहरण सफारी, फ़ायरफ़ॉक्स और क्रोम नाइटलाइज़ में हैं जहां केवल argumentsऑब्जेक्ट को संदर्भित करना फ़ंक्शन को बहुत धीमा बनाता है - जैसे। अगर (झूठा) तर्क; पूर्ण चोट लगी होगी।
olliej

48
एक ही नस में, तर्कों में एक "कैली" संपत्ति है जो वर्तमान कार्य है। यह गुमनाम कार्यों के साथ पुनरावृत्ति करने की अनुमति देता है, अच्छा!
विंसेंट रॉबर्ट

4
@ नथन "f (x, y, z)" "f ([x, y, z])" से बेहतर दिखता है।
मार्क सिडेड

16
@ विंसेंट रॉबर्ट: कृपया ध्यान दें कि arguments.calleeपदावनत किया जा रहा है।
केन

204

मैं ज्यादातर डगलस क्रॉकफोर्ड की उत्कृष्ट पुस्तक जावास्क्रिप्ट: द गुड पार्ट्स उद्धृत कर सकता हूं ।

लेकिन मैं तुम्हारे लिए सिर्फ एक ले जाऊंगा, हमेशा उपयोग करूंगा ===और !==बदले में ==और!=

alert('' == '0'); //false
alert(0 == ''); // true
alert(0 =='0'); // true

==सकर्मक नहीं है। यदि आप इसका उपयोग ===करते हैं तो उम्मीद के अनुसार इन सभी कथनों के लिए गलत होगा।


29
यह शर्म की बात है कि इतने सारे लोगों को लगता है कि क्रॉकफोर्ड सभी जानते हैं। दी, आदमी अपनी अधिकांश आलोचनाओं के साथ निशान पर सही है, लेकिन मैं उसके सामान को कम्बल देने का बंद कर देता हूं, जैसे बहुत सारे देव करते हैं ...
जेसन बंटिंग

21
मैं जेसन की दूसरी चेतावनी। अपने आप में पुस्तक बहुत ही रोचक है, और यह बहुत अच्छी सलाह देती है, लेकिन डीसी अब तक आश्वस्त हैं कि चीजों को करने का उनका एकमात्र तरीका सही है, बाकी सब कुछ "दोषपूर्ण" है। यदि आप कुछ उदाहरण चाहते हैं, तो JSLint याहू ग्रुप पर उनकी प्रतिक्रियाओं को देखें।
Zilk

30
यदि आप डायनामिक टाइपिंग से भ्रमित हैं, तो === के बजाय === का उपयोग करना अच्छी सलाह है और यह चाहते हैं कि यह "वास्तव में" के बराबर हो। हममें से जो डायनेमिक टाइपिंग को समझते हैं, वे उन स्थितियों के लिए == का उपयोग करना जारी रख सकते हैं, जहां हम जानते हैं कि हम कास्ट करना चाहते हैं, जैसा कि 0 == '' या 0 == '0' में है।
thomasrutter

20
वेल == और === डायनामिक टाइपिंग के बारे में नहीं हैं। == एक प्रकार का जानवर है, जो एक अलग जानवर है। यदि आप जानते हैं, कि आप स्ट्रिंग / संख्या / आदि को कास्ट करना चाहते हैं, तो आप स्पष्ट रूप से ऐसा करते हैं।
रेने सारसो

15
मुझे लगता है कि यह सबसे महत्वपूर्ण हिस्सा ==है '\n\t\r ' == 0=> true...: डी
श्रीकांत शरत

189

जावास्क्रिप्ट में फ़ंक्शंस प्रथम श्रेणी के नागरिक हैं:

var passFunAndApply = function (fn,x,y,z) { return fn(x,y,z); };

var sum = function(x,y,z) {
  return x+y+z;
};

alert( passFunAndApply(sum,3,4,5) ); // 12

सुरुचिपूर्ण जावास्क्रिप्ट लिखने के लिए कार्यात्मक प्रोग्रामिंग तकनीकों का उपयोग किया जा सकता है

विशेष रूप से, कार्यों को मापदंडों के रूप में पारित किया जा सकता है, जैसे Array.filter () एक कॉलबैक स्वीकार करता है:

[1, 2, -1].filter(function(element, index, array) { return element > 0 });
// -> [1,2]

आप एक "निजी" फ़ंक्शन भी घोषित कर सकते हैं जो केवल एक विशिष्ट फ़ंक्शन के दायरे में मौजूद है:

function PrintName() {
    var privateFunction = function() { return "Steve"; };
    return privateFunction();
}

3
जावास्क्रिप्ट में फ़ंक्शन करने के तीन तरीके हैं: फ़ंक्शन राशि (x, y, z) {वापसी (x + y + z); } और var योग = नया फ़ंक्शन ("x", "y", "z", "वापसी (x + y + z);"); अन्य तरीके हैं।
मारीस

6
फ़ंक्शंस-एज़-डेटा की अवधारणा निश्चित रूप से मेरी पुस्तक में बड़े बिंदुओं को जीतती है।
जेसन बंटिंग

मैंने सिर्फ एक "निजी" फ़ंक्शन का उपयोग करने के लिए नमूना दिखाया, जो केवल एक विशिष्ट फ़ंक्शन के दायरे में मौजूद है।
बजे क्रिस पिसेट्समैन

new Function()के रूप में बुराई के रूप में है eval। प्रयोग नहीं करें।
निकोलस

11
सुनिश्चित नहीं है कि यह एक छिपी हुई विशेषता है ... मूल विशेषता की तरह।
क्लाउडीयू

162

यदि कोई कुंजी किसी ऑब्जेक्ट में मौजूद है, तो आप ऑपरेटर का उपयोग कर सकते हैं :

var x = 1;
var y = 3;
var list = {0:0, 1:0, 2:0};
x in list; //true
y in list; //false
1 in list; //true
y in {3:0, 4:0, 5:0}; //true

यदि आप वस्तु के शाब्दिक रूप से बहुत अधिक बदसूरत हैं, तो आप इसे पैरामीटर रहित टिप के साथ जोड़ सकते हैं:

function list()
 { var x = {};
   for(var i=0; i < arguments.length; ++i) x[arguments[i]] = 0;
   return x
 }

 5 in list(1,2,3,4,5) //true

22
इतना चतुर नहीं है, कि अगर कोई कुंजी मौजूद है, तो चेक करता है कि क्या कोई मूल्य नहीं है। सूची में x; केवल इसलिए काम करता है क्योंकि x [1]! = शून्य है, इसलिए नहीं कि मान 1 है।
अर्मिन रौनाकर

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

34
इसके अलावा, सावधान रहें: ऑपरेटर भी प्रोटोटाइप श्रृंखला का परीक्षण करता है! यदि किसी ने Object.prototype पर '5' नामक एक संपत्ति डाल दी है, तो दूसरा उदाहरण सही होगा यदि आप '5 को सूची में (1, 2, 3, 4)' कहते हैं ... तो आप बेहतर hasOwnProperty का उपयोग करेंगे विधि: सूची (1, 2, 3, 4) .hasOwnProperty (5) गलत होगी, भले ही Object.prototype के पास '5' गुण हो।
मार्टिन्न

3
बहुत ही सामान्य समाधान के लिए, एक परीक्षण कर सकता है कि क्या किसी वस्तु की अपनी संपत्ति है, भले ही इसे "hasOwnProperty" नाम दिया गया हो, आपको सभी तरह से बाहर जाना होगा: Object.prototyp.hasOwnPropert.call (ऑब्जेक्ट, नाम) ;
क्रिश कोवल सेप

1
@ क्रिस, तब तक नहीं जब तक कि कोई व्यक्ति Object.prototype.hasOwnProperty;) को नहीं लिखता
निक

153

चर के लिए डिफ़ॉल्ट मान असाइन करना

आप ||डिफ़ॉल्ट मान प्रदान करने के लिए असाइनमेंट एक्सप्रेशन में तार्किक या ऑपरेटर का उपयोग कर सकते हैं :

var a = b || c;

aचर के मूल्य मिल जाएगा cकेवल अगर bहै falsy (यदि है null, false, undefined, 0, empty string, या NaN), अन्यथा aका मूल्य मिल जाएगा b

यह अक्सर कार्यों में उपयोगी होता है, जब आप आपूर्ति नहीं होने की स्थिति में तर्क के लिए एक डिफ़ॉल्ट मान देना चाहते हैं:

function example(arg1) {
  arg1 || (arg1 = 'default value');
}

उदाहरण के ईवेंट हैंडलर में IE फॉलबैक:

function onClick(e) {
    e || (e = window.event);
}

निम्नलिखित भाषा सुविधाएँ लंबे समय से हमारे साथ हैं, सभी जावास्क्रिप्ट कार्यान्वयन उनका समर्थन करते हैं, लेकिन वे ECMAScript 5 वें संस्करण तक विनिर्देश का हिस्सा नहीं थे :

debuggerकथन

इसमें वर्णित: .1 12.15 डिबगर कथन

यह कथन आपको केवल अपने कोड में प्रोग्राम के अनुसार ब्रेकपॉइंट लगाने की अनुमति देता है:

// ...
debugger;
// ...

यदि कोई डिबगर मौजूद है या सक्रिय है, तो यह तुरंत उस रेखा पर टूटने का कारण होगा।

अन्यथा, यदि डिबगर मौजूद नहीं है या सक्रिय नहीं है, तो इस कथन का कोई प्रभाव नहीं है।

मल्टीलाइन स्ट्रिंग शाब्दिक

इसमें वर्णित:: 7.8.4 स्ट्रिंग साहित्य

var str = "This is a \
really, really \
long line!";

आपको सावधान रहना होगा क्योंकि एक पंक्ति टर्मिनेटर के आगे का चरित्र \ होना चाहिए, यदि आपके पास \उदाहरण के लिए एक स्थान है , तो कोड बिल्कुल समान दिखाई देगा , लेकिन यह एक बढ़ाएगा SyntaxError


28
अगर यह गलत माना जाता है, तो यह शून्य नहीं है। a = 0 || 42; आपको 42 देंगे। यह पायथन के साथ तुलनीय है, न कि C # का ?? ऑपरेटर। यदि आप C # व्यवहार चाहते हैं, तो a = (b === null) करें? सी: बी;
अर्मिन रोनाचेर

यह विज़ुअल स्टूडियो में भी काम करता है, अगर आप ASP.NET पर विकसित होते हैं :)
chakrit

2
काश वहाँ उचित होता || केवल अपरिभाषित के लिए। मुझे आज 0 से काट लिया गया था, क्योंकि मैं ओवरलोड विधि का अनुकरण बनाना चाहता था, ताकि अंतिम तर्क वैकल्पिक हो और इसके बजाय एक डिफ़ॉल्ट मान का उपयोग किया जा सके।
जैसे इगागा

+1 यह ट्रिक डिफ़ॉल्ट Google Analytics स्निपेट द्वारा उपयोग की जाती है। `वर _गक = _गक || []; `; यह अत्यधिक उपयोगकर्ताओं को अपने स्वयं के काम को अधिलेखित करने से रोकता है।
याहल नोव

2
मैं बहुस्तरीय स्ट्रिंग शाब्दिक तकनीक के बारे में नहीं जानता था। यह शानदार है, धन्यवाद।
चार्ली फूल

145

जावास्क्रिप्ट में ब्लॉक स्कोप नहीं है (लेकिन यह क्लोजर है इसलिए इसे भी कॉल करें?)।

var x = 1;
{
   var x = 2;
}
alert(x); // outputs 2

3
वह वाला अच्छा है। यह अधिकांश सी जैसे भाषाओं से वास्तव में महत्वपूर्ण अंतर है।
मार्टिन क्लार्क

9
आप हमेशा "var tmp = function () {/ * ब्लॉक स्कोप * /} ()" कर सकते हैं। वाक्य विन्यास बदसूरत है, लेकिन यह काम करता है।
जोएरी सेब्रचेट्स

3
या आप "लेट" का उपयोग कर सकते हैं यदि यह केवल फ़ायरफ़ॉक्स है: stackoverflow.com/questions/61088/…
यूजीन योकोटा

10
या बस: (फ़ंक्शन () {var x = 2;}) (); चेतावनी (टाइपो x); // अपरिभाषित
पिम जगेर

@Pim: JSLint का कहना है: "इनवोकेशन को उन पार्न्स में स्थानांतरित करें जिनमें फ़ंक्शन होता है।" साथ ही "फंक्शन 'और' ('" के बीच एक ही स्थान की अपेक्षा की।)
हैलो 71

144

आप के []बजाय के साथ ऑब्जेक्ट गुण तक पहुँच सकते हैं.

यह आपको एक वैरिएबल से मेल खाते गुण को देखने की अनुमति देता है।

obj = {a:"test"};
var propname = "a";
var b = obj[propname];  // "test"

आप इसका उपयोग ऑब्जेक्ट गुण प्राप्त करने / सेट करने के लिए भी कर सकते हैं, जिसका नाम एक कानूनी पहचानकर्ता नहीं है।

obj["class"] = "test";  // class is a reserved word; obj.class would be illegal.
obj["two words"] = "test2"; // using dot operator not possible with the space.

कुछ लोगों को यह पता नहीं है और यह इस तरह से eval () का उपयोग कर समाप्त होता है, जो वास्तव में एक बुरा विचार है :

var propname = "a";
var a = eval("obj." + propname);

यह पढ़ने में कठिन है, त्रुटियों को खोजने के लिए कठिन है (jslint का उपयोग नहीं कर सकते हैं), निष्पादित करने के लिए धीमा है, और XSS कारनामों को जन्म दे सकता है।


eval बुराई है, हालांकि शायद ही कभी आवश्यक है
डौग Domeny

मैं कभी भी इवल का उपयोग नहीं करता हूं और याद करता हूं कि जब मैंने यह खोज की थी। इसने मुझे बहुत खुश किया।

सारांश में, वस्तु गुणों को डॉट और सबस्क्रिप्ट नोटेशन के माध्यम से पहुँचा जा सकता है
Russ Cam

9
यह ध्यान रखना दिलचस्प है कि डॉट-रेफ़रिंग वास्तव में ब्रैकेट के लिए सिंटैक्स चीनी है। foo.barवैसे भी, कल्पना के अनुसार, बस की तरह व्यवहार करता है foo["bar"]। यह भी ध्यान दें कि सब कुछ एक स्ट्रिंग संपत्ति है। जब आप सरणी एक्सेस करते हैं, तब भी array[4], 4 को एक स्ट्रिंग में बदल दिया जाता है (फिर से, कम से कम ECMAScript v3 कल्पना के अनुसार)
क्लाउडी

मुझे लगता है कि हर जेएस प्रोग्रामर को यह जानना चाहिए।
केम कल्याणको

144

यदि आप किसी दिए गए विषय पर एक सभ्य जावास्क्रिप्ट संदर्भ के लिए Googling कर रहे हैं, तो अपनी क्वेरी में "mdc" कीवर्ड शामिल करें और आपके पहले परिणाम मोज़िला डेवलपर केंद्र से होंगे। मैं अपने साथ कोई ऑफ़लाइन संदर्भ या पुस्तकें नहीं रखता हूं। मैं हमेशा "mdc" कीवर्ड ट्रिक का उपयोग करता हूं, जिसे मैं सीधे देख रहा हूं। उदाहरण के लिए:

Google: जावास्क्रिप्ट सरणी सॉर्ट mdc
(ज्यादातर मामलों में आप "जावास्क्रिप्ट" को छोड़ सकते हैं)

अद्यतन: मोज़िला डेवलपर केंद्र का नाम बदलकर मोज़िला डेवलपर नेटवर्क कर दिया गया है । "Mdc" कीवर्ड ट्रिक अभी भी काम करती है, लेकिन जल्द ही हमें इसके बजाय "mdn" का उपयोग शुरू करना पड़ सकता है ।


50
वाह, बढ़िया संसाधन। गंदे w3schools की तुलना में तुरंत बेहतर ...
असंतुष्ट

11
यदि आप फ़ायरफ़ॉक्स पर हैं, तो आपको इसके लिए Google की भी आवश्यकता नहीं है: एड्रेस बार में "सरणी mdc" टाइप करें और एंटर दबाएं।
साशा चोडगोव 4

2
सबसे अच्छा हिस्सा यह है कि यह स्टैक ओवरफ्लो प्रश्न परिणाम के पहले पृष्ठ पर कैसे है :)
जियारो

5
एक प्रोपो यह: प्रमोशन.कॉम , एक जमीनी स्तर की एसईओ पहल जो कि एमडीसी के परिणामों को Google खोज परिणामों में आगे बढ़ाने के लिए प्रेरित करती है।
याहेल नोव

3
अब एमडीएन डॉक सेंटर है, इसलिए 'mdc' कीवर्ड अभी भी मान्य है :)
अलिदाम

143

शायद कुछ के लिए थोड़ा स्पष्ट ...

फायरबग स्थापित करें और कंसोल.लॉग ("हैलो") का उपयोग करें । रैंडम अलर्ट () का उपयोग करने से बहुत बेहतर है, जो मुझे कुछ साल पहले बहुत याद है।


12
बस अपने कोड को उन लोगों को जारी करने से पहले कंसोल स्टेटमेंट को हटाना न भूलें, जिनके पास फायरबग इंस्टॉल नहीं हो सकता है।
क्रिस नू सिप

161
function log (msg) {अगर (कंसोल) कंसोल.लॉग (msg) और अलर्ट (msg)}
जोश

4
इससे भी बेहतर, पूर्ववर्ती लॉग स्टेटमेंट '; ;;; और फिर minify आपके लिए इसकी देखभाल करता है। (कम से कम, मैं जिस पर्ल मॉड्यूल का उपयोग करता हूं, उसमें वह विशेषता है, और यह दावा किया गया है कि यह सामान्य है।)
केव

10
जोश: यह काम नहीं करेगा क्योंकि कंसोल परिभाषित नहीं है। आप टाइपोफ़ कंसोल की जाँच कर सकते हैं! == "अपरिभाषित" या window.console।
एली ग्रे

23
हमेशा शामिल करें: यदि (टाइपोफ़ ('कंसोल') == 'अपरिभाषित') {कंसोल = {लॉग: फ़ंक्शन () {}}; } इसके बाद आप कंसोल का उपयोग करना जारी रख सकते हैं। यह सिर्फ कुछ नहीं करता है।
gregmac

120

निजी तरीके

किसी वस्तु के निजी तरीके हो सकते हैं।

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;

    // A private method only visible from within this constructor
    function calcFullName() {
       return firstName + " " + lastName;    
    }

    // A public method available to everyone
    this.sayHello = function () {
        alert(calcFullName());
    }
}

//Usage:
var person1 = new Person("Bob", "Loblaw");
person1.sayHello();

// This fails since the method is not visible from this scope
alert(person1.calcFullName());

16
यह वास्तव में एक निजी कार्य नहीं है - यह एक स्थानीय क्षेत्र में एक फ़ंक्शन चर है।
कीथ

6
यह सच है लेकिन सभी परिचालनात्मक परिभाषाओं से मैं इस पद्धति के बारे में सोच सकता हूं। यह एक ऐसे नाम के साथ कोड का एक ब्लॉक है जिसकी पहुंच राज्य तक है और केवल उस उदाहरण द्वारा देखा जा सकता है। एक निजी पद्धति की आपकी परिभाषा क्या है?
एलन लालडे

14
@Zach, बिल्कुल! यह आसान है, वर्ग-आधारित OO भाषाओं के साथ काम करने के वर्षों के बाद, यह भूलने के लिए कि वे OO अवधारणाओं का केवल एक कार्यान्वयन हैं। बेशक, विभिन्न पुस्तकालय जो जेएस में अर्ध-वर्ग-आधारित ओओ को
रटने का

5
बस सोच रहा था, क्या person1 में लॉ ब्लॉग है? ;-)
ट्रैविस

4
गिरफ्तार विकास के संदर्भ के लिए +1
डोमिनिक

99

क्रॉकफोर्ड के "जावास्क्रिप्ट: द गुड पार्ट्स" में भी उल्लेख किया गया है:

parseInt()खतरनाक है। यदि आप इसे उचित आधार की जानकारी के बिना एक स्ट्रिंग पास करते हैं तो यह अप्रत्याशित संख्या में वापस आ सकता है। उदाहरण के लिए parseInt('010')8, 10 नहीं। 10. आधार को पारसी के पास भेजना सही तरीके से काम करता है:

parseInt('010') // returns 8! (in FF3)
parseInt('010', 10); // returns 10 because we've informed it which base to work with.

13
कोड समीक्षा करते समय, हमेशा इसे देखें। ", 10" को छोड़ना एक सामान्य गलती है जो अधिकांश परीक्षण में किसी का ध्यान नहीं जाता है।
डग डॉमनी

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

4
उपयोग क्यों नहीं Math.floorया Number? 10 === Math.floor("010"); 10 === Number("010");फ्लोट्स:42 === Math.floor("42.69"); 42.69 === Number("42.69");
बस किसी को

1
@ इनफिनिटी यदि पहले से कोई पोस्टेड उत्तर नहीं है, तो आपको चाहिए। मुझे नहीं पता था कि यह बिलकुल ही आसान है क्योंकि यह बिल्ट-इन फंक्शन बिहेवियर को ओवरराइड करता है। बेशक, यह किसी भी कोड पैकेज पर थोड़ा और बारीकी से देखना चाहिए जो वे अन्य साइटों से उधार लेते हैं। यह हानिरहित parseIntकार्य आसानी से किया जा सकता है ताकि कुछ हानिरहित न हो।
बोब-ए-विध्वंसक

6
@ इनफिनिटी: 'कोडिंग त्रुटि' को उजागर करने के लिए fn को फिर से परिभाषित करने के बारे में क्या? __parseInt = parseInt; parseInt = function (str, base) { if (!base) throw new Error(69, "All your base belong to us"); return __parseInt(str, base); }
JBRWilkinson

97

कार्य वस्तुएं हैं और इसलिए इसमें गुण हो सकते हैं।

fn = function (x) {
   // ...
}

fn.foo = 1;

fn.next = function (y) {
  //
}

13
यह एक बहुत ही उपयोगी टिप है। उदाहरण के लिए, आप फ़ंक्शन के गुण के रूप में डिफ़ॉल्ट मान सेट कर सकते हैं। उदाहरण के लिए: myfunc.delay = 100; तब उपयोगकर्ता डिफ़ॉल्ट मान को बदल सकते हैं और सभी फ़ंक्शन कॉल नए डिफ़ॉल्ट मान का उपयोग करेंगे। उदाहरण के लिए: myfunc.delay = 200; myfunc ();
बेलीफिट्ज

उपयोगी ... और खतरनाक!
palswim

मैला दिखता है, एक चर के बजाय इसका उपयोग क्यों करें?
इंस्टैंटसेट्सुना

1
@instantsetsuna: क्यों एक और अलग चर है? हमेशा की तरह इस करने पर निर्भर करता ;-) "यह जब उचित / उपयोगी का उपयोग करें"
VolkerK

91

मुझे स्वयं-निष्पादित कार्यों को कहना होगा।

(function() { alert("hi there");})();

यदि जावास्क्रिप्ट में ब्लॉक स्कोप नहीं है , तो यदि आप स्थानीय चर को परिभाषित करना चाहते हैं, तो आप एक स्व-निष्पादित फ़ंक्शन का उपयोग कर सकते हैं:

(function() {
  var myvar = 2;
  alert(myvar);
})();

यहां, myvarवैश्विक स्कोप को प्रदूषित या प्रदूषित नहीं करता है, और फ़ंक्शन समाप्त होने पर गायब हो जाता है।


2
यह किसके लिए उपयोगी है? आपको फ़ंक्शन के बाहर अलर्ट डालने से समान परिणाम मिलते हैं।
आलूग्वेनियर

7
यह अलर्ट के बारे में नहीं है, यह एक ही बार में किसी फ़ंक्शन को परिभाषित करने और निष्पादित करने के बारे में है। आपके पास यह हो सकता है कि स्वयं-निष्पादित फ़ंक्शन एक मान लौटाए और फ़ंक्शन को किसी अन्य फ़ंक्शन के लिए एक पैराम के रूप में पास करें।
स्कॉटकून

5
@Paul यह एनकैप्सुलेशन के लिए अच्छा है।
माइक रॉबिन्सन

22
यह ब्लॉक स्कूपिंग के लिए भी अच्छा है।
जिम हंज़िकर

24
हाँ, मैं अपनी सभी .jsफाइलों को एक गुमनाम सेल्फ एग्जीक्यूटिंग फंक्शन में संलग्न करता हूं और जो कुछ भी मैं चाहता हूं, उसे windowवस्तु के भीतर पहुंचाना चाहता हूं । वैश्विक नामस्थान प्रदूषण को रोकता है।
cdmckay

83

जानिए किसी फंक्शन से कितने पैरामीटर की उम्मीद की जाती है

function add_nums(num1, num2, num3 ){
    return num1 + num2 + num3;
}
add_nums.length // 3 is the number of parameters expected.

फ़ंक्शन द्वारा कितने पैरामीटर प्राप्त किए जाते हैं

function add_many_nums(){
    return arguments.length;
}    
add_many_nums(2,1,122,12,21,89); //returns 6

23
पहले भाग के बारे में कभी नहीं पता था। अच्छा!
mcjabberz

1
इसी तरह आप यह पता लगा सकते हैं कि एक फ़ंक्शन कितने तर्कों की अपेक्षा कर रहा है function.length
ज़ावी

6
@Xavi जो जवाब का 1 हिस्सा है
pramodc84

79

यहां कुछ दिलचस्प बातें हैं:

  • NaNकिसी भी चीज के साथ तुलना (यहां तक ​​कि NaN) हमेशा झूठी होती है, जिसमें शामिल है ==, <और >
  • NaN नंबर के लिए खड़ा है, लेकिन अगर आप उस प्रकार के लिए पूछते हैं जो वास्तव में एक नंबर देता है।
  • Array.sort एक तुलनित्र फ़ंक्शन ले सकता है और इसे क्विकसॉर्ट-जैसे ड्राइवर (कार्यान्वयन पर निर्भर करता है) द्वारा बुलाया जाता है।
  • नियमित अभिव्यक्ति "स्थिरांक" राज्य को बनाए रख सकती है, आखिरी चीज की तरह जो वे मेल खाते थे।
  • जावास्क्रिप्ट के कुछ संस्करणों का उपयोग करने के लिए आप की अनुमति देते हैं $0, $1, $2एक regex पर सदस्य हैं।
  • nullकुछ और के विपरीत है। यह न तो एक वस्तु है, न ही एक बूलियन है, एक संख्या है, एक स्ट्रिंग है, न ही है undefined। यह एक "वैकल्पिक" जैसा है undefined। (नोट: typeof null == "object")
  • सबसे बाहरी संदर्भ में, thisअन्यथा अनुपयोगी [वैश्विक] वस्तु की पैदावार होती है।
  • चर की varस्वचालित घोषणा पर निर्भर होने के बजाय एक चर की घोषणा करना , रनटाइम को चर में प्रवेश का अनुकूलन करने का एक वास्तविक मौका देता है।
  • withनिर्माण इस तरह के optimzations को नष्ट कर देगा
  • चर नामों में यूनिकोड वर्ण हो सकते हैं।
  • जावास्क्रिप्ट नियमित अभिव्यक्ति वास्तव में नियमित नहीं हैं। वे पर्ल के रेगेक्स पर आधारित हैं, और लुकाहेड्स के साथ अभिव्यक्ति का निर्माण करना संभव है जो मूल्यांकन करने के लिए बहुत, बहुत लंबा समय लेते हैं।
  • ब्लॉक को लक्ष्य के रूप में लेबल और उपयोग किया जा सकता है break। लूप्स को लेबल और के लक्ष्य के रूप में उपयोग किया जा सकता है continue
  • ऐरे विरल नहीं हैं। अन्यथा खाली सरणी के 1000 वें तत्व को सेट करके इसे भरना चाहिए undefined। (कार्यान्वयन पर निर्भर करता है)
  • if (new Boolean(false)) {...}{...}ब्लॉक निष्पादित करेगा
  • जावास्क्रिप्ट के नियमित अभिव्यक्ति इंजन विशिष्ट हैं: उदाहरण के लिए "गैर-पोर्टेबल" नियमित अभिव्यक्ति लिखना संभव है।

[अच्छी टिप्पणियों के जवाब में थोड़ा अपडेट किया गया; कृपया टिप्पणियां देखें]


5
नल वास्तव में (विशेष) वस्तु है। typeof null"वस्तु" लौटाता है।
एटलेस गोरल

4
आप इस तरह से कहीं से भी [Global] ऑब्जेक्ट प्राप्त कर सकते हैं: var glb = function () {इसे वापस करें; } ();
Zilk

2
एक ब्राउज़र में जावास्क्रिप्ट में वैश्विक ऑब्जेक्ट विंडो ऑब्जेक्ट है। जब वैश्विक दायरे में कर रहे हैं: window.a == a;
पीम जगर

8
"ऐरे विरल नहीं हैं" कार्यान्वयन पर निर्भर करता है। यदि आप एक [१०००] का मूल्य निर्धारित करते हैं और एक [९९९] को देखते हैं, तो हाँ, यह है undefined, लेकिन यह केवल एक डिफ़ॉल्ट मान है जो आपको एक इंडेक्स की तलाश में मिलता है जो मौजूद नहीं है। यदि आपने [2000] की जाँच की, तो यह भी होगा undefined, लेकिन इसका मतलब यह नहीं है कि आपने इसके लिए मेमोरी आवंटित नहीं की है। IE8 में, कुछ सरणियाँ सघन हैं, और कुछ विरल हैं, जो इस बात पर निर्भर करता है कि उस समय JScript इंजन कैसा लगा था। यहाँ और अधिक पढ़ें: blogs.msdn.com/jscript/archive/2008/04/08/…
क्रिस नील्सन

2
@Ates और @SF: टाइपोफ़ विभिन्न प्रकार की श्रेणी के लिए "ऑब्जेक्ट" लौटाता है। लेकिन एक बार जब आप जानते हैं कि यह कैसे काम करता है और "ऑब्जेक्ट" के रूप में किस प्रकार की पहचान करता है, तो यह कम से कम विश्वसनीय और इसके कार्यान्वयन में सुसंगत है।
थोमसट्रेटर

77

मुझे पता है कि मुझे पार्टी में देरी हो रही है, लेकिन मैं बस विश्वास नहीं कर सकता कि +ऑपरेटर की उपयोगिता का उल्लेख "एक नंबर के लिए कुछ भी कन्वर्ट करने" से परे नहीं किया गया है। हो सकता है कि यह एक विशेषता कितनी अच्छी तरह से छिपा हुआ है?

// Quick hex to dec conversion:
+"0xFF";              // -> 255

// Get a timestamp for now, the equivalent of `new Date().getTime()`:
+new Date();

// Safer parsing than parseFloat()/parseInt()
parseInt("1,000");    // -> 1, not 1000
+"1,000";             // -> NaN, much better for testing user input
parseInt("010");      // -> 8, because of the octal literal prefix
+"010";               // -> 10, `Number()` doesn't parse octal literals 

// A use case for this would be rare, but still useful in cases
// for shortening something like if (someVar === null) someVar = 0;
+null;                // -> 0;

// Boolean to integer
+true;                // -> 1;
+false;               // -> 0;

// Other useful tidbits:
+"1e10";              // -> 10000000000
+"1e-4";              // -> 0.0001
+"-12";               // -> -12

बेशक, आप यह सब Number()इसके बजाय का उपयोग कर सकते हैं , लेकिन +ऑपरेटर इतना सुंदर है!

आप प्रोटोटाइप की valueOf()विधि को ओवरराइड करके किसी ऑब्जेक्ट के लिए संख्यात्मक रिटर्न मान को भी परिभाषित कर सकते हैं । उस वस्तु पर किया गया कोई भी संख्या रूपांतरण परिणाम नहीं देगा NaN, लेकिन valueOf()विधि का वापसी मूल्य :

var rnd = {
    "valueOf": function () { return Math.floor(Math.random()*1000); }
};
+rnd;               // -> 442;
+rnd;               // -> 727;
+rnd;               // -> 718;

आप बस 0xFFआदि कर सकते हैं , कोई ज़रूरत नहीं है +"0xFF"
nyuszika7h

9
@ Nyuszika7H: आप उस बिंदु को याद कर रहे हैं, जो अन्य प्राइमेटिव्स और ऑब्जेक्ट्स को संख्याओं में ले जा रहा है। बेशक आप बस लिख सकते हैं 0xFF, उसी तरह से जिसके 1बजाय आप लिख सकते हैं +true। मैं सुझाव दे रहा हूं कि आप चाहें तो +("0x"+somevar)एक विकल्प के रूप में उपयोग कर सकते हैं parseInt(somevar, 16)
एंडी ई

75

" जावास्क्रिप्ट में विस्तार तरीकों " प्रोटोटाइप संपत्ति के माध्यम से।

Array.prototype.contains = function(value) {  
    for (var i = 0; i < this.length; i++) {  
        if (this[i] == value) return true;  
    }  
    return false;  
}

यह containsसभी Arrayवस्तुओं के लिए एक विधि जोड़ देगा । आप इस सिंटैक्स का उपयोग करके इस विधि को कॉल कर सकते हैं

var stringArray = ["foo", "bar", "foobar"];
stringArray.contains("foobar");

18
यह आमतौर पर एक बुरा विचार माना जाता है, क्योंकि अन्य कोड (आपका नहीं) एरे ऑब्जेक्ट के बारे में धारणा बना सकता है।
क्रिस नू सिप

39
यह आमतौर पर ऐरे ऑब्जेक्ट के बारे में धारणा बनाने के लिए एक बुरा विचार माना जाता है। :(
आंखों की रोशनी

उम्म्मम .. जावास्क्रिप्ट 1.6 सरणी एक्स्ट्रा कलाकार? के सूचकांक? किसी भी घंटी बज रही है?
ब्रेटन

2
@ ब्रेटन: यह ऐरे वर्ग के लिए कुछ खास नहीं है, यह सिर्फ एक उदाहरण है। मैं इसका उपयोग नई तिथि () .String () को बढ़ाने के लिए करता हूं; विधि, एक मुखौटा स्ट्रिंग का उपयोग करने की अनुमति। किसी भी वस्तु को बढ़ाया जा सकता है, और सभी उदाहरणों में नई विधि मिलती है।
एस्टेबन कुबेर

1
@ माथियास: यह डोम के बारे में नहीं है।
डोलमेन

60

किसी ऑब्जेक्ट से किसी प्रॉपर्टी को ठीक से निकालने के लिए, आपको उसे अपरिभाषित करने के लिए सेट करने के बजाय प्रॉपर्टी को हटा देना चाहिए :

var obj = { prop1: 42, prop2: 43 };

obj.prop2 = undefined;

for (var key in obj) {
    ...

संपत्ति Prop2 अभी भी पुनरावृत्ति का हिस्सा होगा। यदि आप Prop2 से पूरी तरह से छुटकारा चाहते हैं , तो आपको इसके बजाय करना चाहिए:

delete obj.prop2;

प्रॉपर्टी के माध्यम से पुनरावृत्ति करने पर प्रॉपर्टी प्रोप 2 अब दिखाई नहीं देगा।


3
ध्यान दें कि डिलीट स्टेटमेंट इसके ब्राउज़र-विशिष्ट क्विर्क्स के बिना नहीं है। उदाहरण के लिए यह एक बड़ी त्रुटि के साथ विफल हो जाएगा यदि आप इसे IE में कोशिश करते हैं और ऑब्जेक्ट एक देशी जेएस ऑब्जेक्ट नहीं है (यहां तक ​​कि जब आपने खुद को जोड़ा संपत्ति को हटाते हुए भी)। यह एक चर को हटाने के लिए भी इरादा नहीं है, जैसा कि myvar को हटाना है; लेकिन मुझे लगता है कि यह कुछ ब्राउज़रों में काम करता है। उपरोक्त उत्तर में कोड हालांकि बहुत सुरक्षित लगता है।
थोमसट्रेटर

वैसे, अपरिभाषित एक चर भी हो सकता है! Var अपरिभाषित = "कुछ" की कोशिश करें
जोहान फिलिप स्ट्रैटहॉसन

57

with

यह शायद ही कभी इस्तेमाल किया जाता है, और स्पष्ट रूप से, शायद ही कभी उपयोगी ... लेकिन, सीमित परिस्थितियों में, इसके उपयोग होते हैं।

उदाहरण के लिए: किसी नए ऑब्जेक्ट पर जल्दी से गुण स्थापित करने के लिए ऑब्जेक्ट शाब्दिक रूप से काफी आसान है । लेकिन क्या होगा यदि आपको किसी मौजूदा ऑब्जेक्ट पर आधे गुणों को बदलने की आवश्यकता है ?

var user = 
{
   fname: 'Rocket', 
   mname: 'Aloysus',
   lname: 'Squirrel', 
   city: 'Fresno', 
   state: 'California'
};

// ...

with (user)
{
   mname = 'J';
   city = 'Frostbite Falls';
   state = 'Minnesota';
}

एलन स्टॉर्म बताते हैं कि यह कुछ खतरनाक हो सकता है: यदि संदर्भ के रूप में उपयोग की जाने वाली वस्तु में से एक को सौंपा नहीं जा रहा है, तो यह बाहरी दायरे में हल किया जाएगा, संभवत: एक वैश्विक चर का निर्माण या ओवरराइटिंग। यह विशेष रूप से खतरनाक है यदि आप उन वस्तुओं के साथ काम करने के लिए कोड लिखने के लिए उपयोग किए जाते हैं जहां डिफ़ॉल्ट या खाली मान वाले गुण अपरिभाषित रह गए हैं:

var user = 
{
   fname: "John",
// mname definition skipped - no middle name
   lname: "Doe"
};

with (user)
{
   mname = "Q"; // creates / modifies global variable "mname"
}

इसलिए, withइस तरह के असाइनमेंट के लिए स्टेटमेंट के उपयोग से बचना शायद एक अच्छा विचार है ।

यह भी देखें: क्या जावास्क्रिप्ट के "कथन" के लिए वैध उपयोग हैं?


29
प्रतिमा के साथ पारंपरिक ज्ञान से बचा जाना है। यदि उपयोगकर्ता ऑब्जेक्ट में आपके द्वारा बताए गए गुणों में से एक नहीं है, तो ब्लॉक के छद्म दायरे के साथ बाहर चर को संशोधित किया जाएगा। इस तरह से कीड़े पड़ते हैं। Yuiblog.com/blog/2006/04/11/with-statement-considered-harmful
एलन स्टॉर्म

1
शोग, आपत्तियाँ गलत वर्तनी वाले चर के बारे में नहीं हैं, वे कोड के एक ब्लॉक को देखने के बारे में हैं, और निश्चित रूप से यह कहने में सक्षम हैं कि उस ब्लॉक में कोई विशेष रेखा क्या है। क्योंकि जावास्क्रिप्ट ऑब्जेक्ट बहुत गतिशील होते हैं, आप निश्चित रूप से यह नहीं कह सकते हैं कि किसी भी क्षण इसमें क्या गुण / सदस्य हैं।
एलन स्टॉर्म

2
आमीन - अगर मुझे किसी भी जेएस में "" के साथ "बयान मिला, तो मैं इसे खत्म कर दूंगा और डेवलपर से सवाल करूंगा कि यह सुनिश्चित करने के लिए कि वह जानता था कि इसका इस्तेमाल करने के लिए यह गुड थिंग क्यों नहीं था ..." छिपी हुई विशेषता? " अधिक "घिनौनी विशेषता" की तरह।
जेसन बंटिंग

1
एक और अधिक जटिल श्रृंखला abcd पर विचार करें "(abc) {d.foo = बार?} शक्तिशाली है और इसमें कोई त्रुटि त्रुटि नहीं है। कुंजी एक स्तर तक जड़ को घुमाने के लिए है। और एक चर नाम को गलत करने के लिए? आप बग का परिचय दे रहे हैं। अगर आप ऐसा करते हैं, तो आप जहां भी करते हैं, "परवाह" के बिना।
annakata

4
डगलस क्रॉकफोर्ड ने हाल ही में कहा कि "के साथ" .NET चट्टानों में जावास्क्रिप्ट के सबसे खराब हिस्सों में से एक है! पॉडकास्ट।
कोर

51

विधियों (या कार्यों) को ऑब्जेक्ट पर बुलाया जा सकता है जो उस प्रकार के नहीं हैं जिनके साथ वे काम करने के लिए डिज़ाइन किए गए थे। यह कस्टम ऑब्जेक्ट्स पर देशी (तेज़) विधियों को कॉल करने के लिए बहुत अच्छा है।

var listNodes = document.getElementsByTagName('a');
listNodes.sort(function(a, b){ ... });

यह कोड क्रैश हो listNodesजाता है क्योंकि कोई नहीं हैArray

Array.prototype.sort.apply(listNodes, [function(a, b){ ... }]);

यह कोड काम करता है क्योंकि इसके listNodesद्वारा उपयोग की जाने वाली पर्याप्त सरणी जैसी गुण (लंबाई, [] ऑपरेटर) को परिभाषित करता है sort()


43

प्रोटोटाइप इनहेरिटेंस (डगलस क्रॉकफ़ोर्ड द्वारा लोकप्रिय) पूरी तरह से क्रांति करता है जिस तरह से आप जावास्क्रिप्ट में चीजों के भार के बारे में सोचते हैं।

Object.beget = (function(Function){
    return function(Object){
        Function.prototype = Object;
        return new Function;
    }
})(function(){});

यह एक हत्यारा है! अफ़सोस कि कोई इसका उपयोग कैसे करता है।

यह आपको किसी भी वस्तु के नए उदाहरणों को "भूल" करने की अनुमति देता है, जबकि उनके अन्य गुणों के लिए एक (लाइव) प्रोटोटाइप विरासत लिंक को बनाए रखते हुए उन्हें बढ़ाता है। उदाहरण:

var A = {
  foo : 'greetings'
};  
var B = Object.beget(A);

alert(B.foo);     // 'greetings'

// changes and additionns to A are reflected in B
A.foo = 'hello';
alert(B.foo);     // 'hello'

A.bar = 'world';
alert(B.bar);     // 'world'


// ...but not the other way around
B.foo = 'wazzap';
alert(A.foo);     // 'hello'

B.bar = 'universe';
alert(A.bar);     // 'world'

42

कुछ इसे स्वाद का मामला कहेंगे, लेकिन:

aWizz = wizz || "default";
// same as: if (wizz) { aWizz = wizz; } else { aWizz = "default"; }

इस योजना की तरह कार्य करने के लिए ट्राइनर ऑपरेटर को जंजीर दी जा सकती है ...

(cond (predicate  (action  ...))
      (predicate2 (action2 ...))
      (#t         default ))

के रूप में लिखा जा सकता है ...

predicate  ? action( ... ) :
predicate2 ? action2( ... ) :
             default;

यह बहुत "कार्यात्मक" है, क्योंकि यह साइड इफेक्ट्स के बिना आपके कोड को शाखा करता है। इसलिए इसके बजाय:

if (predicate) {
  foo = "one";
} else if (predicate2) {
  foo = "two";
} else {
  foo = "default";
}

तुम लिख सकते हो:

foo = predicate  ? "one" :
      predicate2 ? "two" :
                   "default";

पुनरावृत्ति के साथ अच्छा काम करता है, :)


मुझे आपके द्वारा दिया गया विधेय वाक्यविन्यास पसंद है। मैंने ऐसा कभी नहीं सोचा है। साफ।
एलेन लालोंडे

2
उह ... जावास्क्रिप्ट में एक स्विच () स्टेटमेंट है। :-)
स्टेटिक्सन

मैं स्विच स्टेटमेंट का बहुत बड़ा प्रशंसक नहीं हूं - वे सी की एक कलाकृति हैं, कार्यात्मक प्रोग्रामिंग नहीं। मेरे उदाहरण में, एक स्विच स्टेटमेंट को अभी भी तीन अलग-अलग बयानों की आवश्यकता होगी, सभी "फू =" से शुरू होते हैं - स्पष्ट रूप से आवश्यक पुनरावृत्ति।
एंड्री फेडोरोव

14
मैं, एक के लिए, टर्नरी ऑपरेटर का स्वागत करता हूं।
thomasrutter

8
फिर से पढ़ने पर, मैं यह बताना चाहता हूं कि यह "कोड को किसी अन्य भाषा की तरह नहीं बना रहा है", लेकिन वास्तव में कोड के अर्थ को सरल करना है: जब आप कहने की कोशिश कर रहे हों "तीन में से एक के लिए फू सेट करें चीजें ", यह एक कथन है जो" फू = ... "से शुरू होना चाहिए, न कि" यदि "।
एंड्री फेदोरोव

41

नंबर भी ऑब्जेक्ट हैं। तो आप शांत सामान कर सकते हैं जैसे:

// convert to base 2
(5).toString(2) // returns "101"

// provide built in iteration
Number.prototype.times = function(funct){
  if(typeof funct === 'function') {
    for(var i = 0;i < Math.floor(this);i++) {
      funct(i);
    }
  }
  return this;
}


(5).times(function(i){
  string += i+" ";
});
// string now equals "0 1 2 3 4 "

var x = 1000;

x.times(function(i){
  document.body.innerHTML += '<p>paragraph #'+i+'</p>';
});
// adds 1000 parapraphs to the document

हे भगवान! मैं स्ट्रींग (मूलांक) के बारे में नहीं जानता था ...
एट्स गोरल

1
यह लागू करना timesकुशल नहीं है: Math.floorहर बार सिर्फ एक बार के बजाय कहा जाता है।
dolmen

33

जावास्क्रिप्ट में बंद होने के बारे में कैसे (C # v2.0 + में अनाम विधियों के समान)। आप एक फ़ंक्शन बना सकते हैं जो एक फ़ंक्शन या "अभिव्यक्ति" बनाता है।

क्लोजर का उदाहरण :

//Takes a function that filters numbers and calls the function on 
//it to build up a list of numbers that satisfy the function.
function filter(filterFunction, numbers)
{
  var filteredNumbers = [];

  for (var index = 0; index < numbers.length; index++)
  {
    if (filterFunction(numbers[index]) == true)
    {
      filteredNumbers.push(numbers[index]);
    }
  }
  return filteredNumbers;
}

//Creates a function (closure) that will remember the value "lowerBound" 
//that gets passed in and keep a copy of it.
function buildGreaterThanFunction(lowerBound)
{
  return function (numberToCheck) {
    return (numberToCheck > lowerBound) ? true : false;
  };
}

var numbers = [1, 15, 20, 4, 11, 9, 77, 102, 6];

var greaterThan7 = buildGreaterThanFunction(7);
var greaterThan15 = buildGreaterThanFunction(15);

numbers = filter(greaterThan7, numbers);
alert('Greater Than 7: ' + numbers);

numbers = filter(greaterThan15, numbers);
alert('Greater Than 15: ' + numbers);

1
मैं अनिश्चित हूं, लेकिन वापस जा सकता हूं (नंबरटॉच> लोअरबाउंड)? सही गलत; बस वापसी (नंबरटॉच> लोअरबाउंड) बनें; बस मेरी समझ बढ़ाने की कोशिश कर रहा हूँ ...
davidsleeps

4
मैं कहता हूँ कि C # में अनाम फ़ंक्शंस क्लोजर के बराबर हैं, न कि दूसरे तरीके से :)
vava

11
क्लोजर और अनाम फ़ंक्शन अलग-अलग हैं, अलग-अलग अवधारणाएं हैं। अनाम फ़ंक्शन होने के बिना कार्य किए जा सकते हैं। कि 'create' स्कोप में एक वैरिएबल निर्मित फंक्शन के साथ जुड़ा हुआ है, एक क्लोजर है। संक्षेप में, एक बंद एक छिपे हुए वैश्विक चर की तरह है।
स्लीबटमैन

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

2
मुझे नहीं लगता कि यह सबसे अच्छा या सबसे आसान उदाहरण है कि एक क्लोजर क्या है। बस केह रहा हू। एक बंद करने की बात यह है कि जब चर का एक गुच्छा 'कार्यक्षेत्र से बाहर चला जाता है' तब भी वे उस फ़ंक्शन के लिए उपलब्ध रह सकते हैं जो मूल रूप से उस दायरे में परिभाषित किया गया था। उपर्युक्त उदाहरण में, इसका मतलब है कि लोअरबाउंड वैरिएबल उस आंतरिक, अनाम फ़ंक्शन द्वारा तब भी पहुंच योग्य है, जब बाहरी फ़ंक्शन, buildGraitThanFunction भी समाप्त हो जाता है।
थोमसट्रेटर

32

आप प्रोटोटाइप श्रृंखला spoon16 का उपयोग करके गुणों (विधियों) को विस्तारित (इनहेरिट) वर्गों और ओवरराइड कर सकते हैं ।

निम्नलिखित उदाहरण में हम एक क्लास पेट बनाते हैं और कुछ गुणों को परिभाषित करते हैं। हम .toString () विधि से विरासत में मिली विधि को भी ओवरराइड करते हैं।

इसके बाद हम एक डॉग क्लास बनाते हैं जो पेट को विस्तारित करता है और .toString () विधि को फिर से बदलकर इसे व्यवहार (बहुरूपता) बनाता है । इसके अलावा हम बच्चे के वर्ग में कुछ अन्य गुण जोड़ते हैं।

इसके बाद, हम दिखावा करने के लिए वंशानुक्रम श्रृंखला की जाँच करते हैं कि कुत्ता अभी भी प्रकार का कुत्ता है, प्रकार का पालतू, और प्रकार का वस्तु।

// Defines a Pet class constructor 
function Pet(name) 
{
    this.getName = function() { return name; };
    this.setName = function(newName) { name = newName; };
}

// Adds the Pet.toString() function for all Pet objects
Pet.prototype.toString = function() 
{
    return 'This pets name is: ' + this.getName();
};
// end of class Pet

// Define Dog class constructor (Dog : Pet) 
function Dog(name, breed) 
{
    // think Dog : base(name) 
    Pet.call(this, name);
    this.getBreed = function() { return breed; };
}

// this makes Dog.prototype inherit from Pet.prototype
Dog.prototype = new Pet();

// Currently Pet.prototype.constructor
// points to Pet. We want our Dog instances'
// constructor to point to Dog.
Dog.prototype.constructor = Dog;

// Now we override Pet.prototype.toString
Dog.prototype.toString = function() 
{
    return 'This dogs name is: ' + this.getName() + 
        ', and its breed is: ' + this.getBreed();
};
// end of class Dog

var parrotty = new Pet('Parrotty the Parrot');
var dog = new Dog('Buddy', 'Great Dane');
// test the new toString()
alert(parrotty);
alert(dog);

// Testing instanceof (similar to the `is` operator)
alert('Is dog instance of Dog? ' + (dog instanceof Dog)); //true
alert('Is dog instance of Pet? ' + (dog instanceof Pet)); //true
alert('Is dog instance of Object? ' + (dog instanceof Object)); //true

इस प्रश्न के दोनों उत्तर रे Djajadinata द्वारा एक महान MSDN लेख से संशोधित कोड थे


31

आप उनके प्रकार के आधार पर अपवादों को पकड़ सकते हैं। MDC से उद्धृत :

try {
   myroutine(); // may throw three exceptions
} catch (e if e instanceof TypeError) {
   // statements to handle TypeError exceptions
} catch (e if e instanceof RangeError) {
   // statements to handle RangeError exceptions
} catch (e if e instanceof EvalError) {
   // statements to handle EvalError exceptions
} catch (e) {
   // statements to handle any unspecified exceptions
   logMyErrors(e); // pass exception object to error handler
}

नोट: सशर्त पकड़ क्लॉज़ एक नेटस्केप (और इसलिए मोज़िला / फ़ायरफ़ॉक्स) एक्सटेंशन है जो ECMAScript विनिर्देश का हिस्सा नहीं है और इसलिए विशेष ब्राउज़रों को छोड़कर इस पर भरोसा नहीं किया जा सकता है।


29
मैं इसकी मदद नहीं कर सका: कैच (मुझे अगर तुम कर सकते हो)
एटेस गोरल

6
एमडीसी पृष्ठ से नोट पढ़ें जिसे आपने उद्धृत किया था: सशर्त पकड़ खंड एक नेटस्केप (और इसलिए मोज़िला / फ़ायरफ़ॉक्स) एक्सटेंशन है जो ECMAScript विनिर्देश का हिस्सा नहीं है और इसलिए विशेष ब्राउज़रों को छोड़कर इस पर भरोसा नहीं किया जा सकता है।
जेसन एस

31

मेरे सर के ऊपर से चला गया...

कार्य

"फ़ंक्शन" चर को होस्ट करने वाले फ़ंक्शन का उपयोग करने के लिए तर्कों को संदर्भित करता है, इसलिए इसका उपयोग अनाम कार्यों को पुनः प्राप्त करने के लिए किया जा सकता है:

var recurse = function() {
  if (condition) arguments.callee(); //calls recurse() again
}

यदि आप ऐसा कुछ करना चाहते हैं तो यह उपयोगी है:

//do something to all array items within an array recursively
myArray.forEach(function(item) {
  if (item instanceof Array) item.forEach(arguments.callee)
  else {/*...*/}
})

वस्तुओं

ऑब्जेक्ट सदस्यों के बारे में एक दिलचस्प बात: उनके नाम के रूप में कोई भी स्ट्रिंग हो सकती है:

//these are normal object members
var obj = {
  a : function() {},
  b : function() {}
}
//but we can do this too
var rules = {
  ".layout .widget" : function(element) {},
  "a[href]" : function(element) {}
}
/* 
this snippet searches the page for elements that
match the CSS selectors and applies the respective function to them:
*/
for (var item in rules) {
  var elements = document.querySelectorAll(rules[item]);
  for (var e, i = 0; e = elements[i++];) rules[item](e);
}

स्ट्रिंग्स

String.split पैरामीटर के रूप में नियमित अभिव्यक्ति ले सकता है:

"hello world   with  spaces".split(/\s+/g);
//returns an array: ["hello", "world", "with", "spaces"]

String.replace खोज पैरामीटर के रूप में एक नियमित अभिव्यक्ति और प्रतिस्थापन पैरामीटर के रूप में एक फ़ंक्शन ले सकता है:

var i = 1;
"foo bar baz ".replace(/\s+/g, function() {return i++});
//returns "foo1bar2baz3"

आपके द्वारा बताई गई बातें ... क्या वे सभी ब्राउज़रों में लागू हैं?
cllpse 14

4
नहीं, मुझे पूरा यकीन है कि मोज़ेक की कमी है।
jsight

2
जावास्क्रिप्ट सुविधाएँ, हाँ, वे सभी प्रमुख ब्राउज़रों (IE6 / 7, FF2 / 3, Opera 9+, Safari2 / 3 और Chrome) में कार्यान्वित की जाती हैं। document.querySelectorAll अभी तक सभी ब्राउज़रों में समर्थित नहीं है (यह JQuery के $ का W3C संस्करण है), और प्रोटोटाइप का $$ ())
Leo

6
arguments.calleeबहिष्कृत है और ECMAScript 5 में फेंक और अपवाद होगा
Hello71

बिल्कुल सच नहीं है। एक ऑब्जेक्ट कुंजी एक नाम के रूप में स्ट्रिंग "hasOwnProperty" का उपयोग नहीं कर सकती है, क्योंकि यह ऑब्जेक्ट विधि में निर्मित को ओवरराइड करेगा।
ब्रेटन

29

आप ज्यादातर समय स्विच के बजाय वस्तुओं का उपयोग कर सकते हैं।

function getInnerText(o){
    return o === null? null : {
        string: o,
        array: o.map(getInnerText).join(""),
        object:getInnerText(o["childNodes"])
    }[typeis(o)];
}

अद्यतन: यदि आप पहले से अक्षम होने के मूल्यांकन के मामलों के बारे में चिंतित हैं (आप कार्यक्रम के डिजाइन में इस दक्षता के बारे में चिंतित क्यों हैं?) तो आप कुछ इस तरह से कर सकते हैं:

function getInnerText(o){
    return o === null? null : {
        string: function() { return o;},
        array: function() { return o.map(getInnerText).join(""); },
        object: function () { return getInnerText(o["childNodes"]; ) }
    }[typeis(o)]();
}

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

अपडेट 2: ES.next के लिए प्रस्तावित सिंटैक्स एक्सटेंशन के साथ, यह बन जाता है

let getInnerText = o -> ({
    string: o -> o,
    array: o -> o.map(getInnerText).join(""),
    object: o -> getInnerText(o["childNodes"])
}[ typeis o ] || (->null) )(o);

3
बिना किसी स्विच स्टेटमेंट के पायथन को यह कैसे पता चलता है।
outis

2
समस्या यह है कि यह हमेशा सभी मामलों का मूल्यांकन करता है।
कोर्नेल

@ चोंचला यह सच है, लेकिन यह कुछ लाभ प्रदान करता है: यह तार्किक रूप से क्लीनर है: मामले ऐसे तार हैं जो एक हैशटेबल पर देखे जाते हैं, न कि उन अभिव्यक्तियों पर जिनमें से प्रत्येक को समानता के लिए मूल्यांकन किया जाना है जब तक कि एक सच न हो। इसलिए जबकि अधिक "मूल्यों" का मूल्यांकन किया जाता है, कम "कुंजियों" का मूल्यांकन किया जाता है। वस्तुओं को गतिशील रूप से उत्पन्न किया जा सकता है, और बाद में स्केलेबिलिटी के लिए संशोधित किया जा सकता है, UI को प्रिंट करने या डॉक्स उत्पन्न करने के लिए परिलक्षित होता है, और यहां तक ​​कि एक गतिशील "लुकअप" फ़ंक्शन के साथ प्रतिस्थापित किया जाता है, जो कॉपी / पेस्ट किए गए मामलों से बेहतर होता है। ब्रेक, फ़ॉल-थ्रू या डिफ़ॉल्ट मानों के बारे में कोई भ्रम नहीं है। JSON धारावाहिक हो सकता है ...
ब्रेटन

@porneL ओह हाँ, और फिर से स्केलेबिलिटी की बात के लिए, एक वस्तु को आसानी से बाहरी कॉन्फ़िगरेशन या डेटा फ़ाइल में बदल दिया जा सकता है, स्विच स्टेटमेंट की तुलना में कुछ हद तक अधिक सरल परिवर्तन- लेकिन तुच्छ हो अगर शुरू करने के लिए किसी वस्तु के साथ डिज़ाइन किया गया हो। साथ में।
ब्रेटन

मुझे पता है कि यह एक देर से प्रविष्टि है, लेकिन जब तक आपके पास कुछ कस्टम टाइप-चेकिंग तर्क नहीं है, तब एक सरणी आपके उदाहरण के साथ कब काम कर रही है? var arr = []; typeof arr; // object
कीगनवाटकिन्स

25

किसी ऑब्जेक्ट के गुणों के माध्यम से पुनरावृत्ति करते समय hasOwnProperty विधि का उपयोग करना सुनिश्चित करें :

for (p in anObject) {
    if (anObject.hasOwnProperty(p)) {
        //Do stuff with p here
    }
}

ऐसा इसलिए किया जाता है ताकि आप केवल किसी प्रत्यक्ष वस्तु के प्रत्यक्ष गुणों तक पहुंच प्राप्त कर सकें , और उन संपत्तियों का उपयोग न करें जो प्रोटोटाइप श्रृंखला के नीचे हैं।


23

एक सार्वजनिक इंटरफ़ेस के साथ निजी चर

यह एक स्व-कॉलिंग फ़ंक्शन परिभाषा के साथ एक साफ छोटी चाल का उपयोग करता है। जो वस्तु वापस दी गई है उसके अंदर सब कुछ सार्वजनिक इंटरफ़ेस में उपलब्ध है, जबकि बाकी सब कुछ निजी है।

var test = function () {
    //private members
    var x = 1;
    var y = function () {
        return x * 2;
    };
    //public interface
    return {
        setx : function (newx) {
            x = newx;
        },
        gety : function () {
            return y();
        }
    }
}();

assert(undefined == test.x);
assert(undefined == test.y);
assert(2 == test.gety());
test.setx(5);
assert(10 == test.gety());

1
इसे मॉड्यूल पैटर्न कहा जाता है, जैसा कि डब किया गया था कि एरिक मिरगलिया द्वारा युइब्लॉग . com / blog / 2007 / 06 / 12 / module-pattern पर मुझे लगता है कि नाम भ्रामक है, इसे सिंगलटन पैटर्न या ऐसा कुछ कहा जाना चाहिए। मैं यह भी जोड़ सकता हूँ कि सार्वजनिक विधियाँ 'इस' ऑब्जेक्ट का उपयोग करके अन्य सार्वजनिक विधियों को भी कॉल कर सकती हैं। मैं अपने कोड को व्यवस्थित और साफ रखने के लिए हर समय इस पैटर्न का उपयोग करता हूं।
mikeycgto
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.