अन्य जानकारी

प्रोटोटाइप इनहेरिटेंस

null और undefined को छोड़कर, हर तरह के शुरुआती डेटा में प्रोटोटाइप, एक संबंधित ऑब्जेक्ट रैपर है, जो काम करने के तरीके बताता है इस्तेमाल करें. जब किसी प्रिमिटिव पर किसी मेथड या प्रॉपर्टी लुकअप का शुरू किया जाता है, JavaScript ने शुरुआती जानकारी को पर्दे के पीछे के हिस्से के तौर पर सेव किया है और पुष्टि करने के तरीके को या इसके बजाय, रैपर ऑब्जेक्ट पर प्रॉपर्टी लुकअप करता है.

उदाहरण के लिए, स्ट्रिंग लिटरल के खुद का कोई तरीका नहीं होता है, लेकिन आप इस पर .toUpperCase() तरीका लागू होता है. यह उससे जुड़े String ऑब्जेक्ट की वजह से मुमकिन हो पाया रैपर:

"this is a string literal".toUpperCase();
> THIS IS A STRING LITERAL

इसे प्रोटोटाइप इनहेरिटेंस कहा जाता है—प्रॉपर्टी में मौजूद प्रॉपर्टी और मेथड .

Number.prototype
> Number { 0 }
>  constructor: function Number()
>  toExponential: function toExponential()
>  toFixed: function toFixed()
>  toLocaleString: function toLocaleString()
>  toPrecision: function toPrecision()
>  toString: function toString()
>  valueOf: function valueOf()
>  <prototype>: Object { … }

किसी भी कंस्ट्रक्टर का इस्तेमाल करके, प्रिमिटिव बनाए जा सकते हैं. उन्हें उनके मूल्य के हिसाब से देखते हैं. उदाहरण के लिए, String कंस्ट्रक्टर का इस्तेमाल करने से स्ट्रिंग ऑब्जेक्ट, न कि स्ट्रिंग लिटरल: एक ऐसा ऑब्जेक्ट जिसमें न सिर्फ़ हमारी स्ट्रिंग वैल्यू, लेकिन कंस्ट्रक्टर की इनहेरिट की गई सभी प्रॉपर्टी और मेथड हैं.

const myString = new String( "I'm a string." );

myString;
> String { "I'm a string." }

typeof myString;
> "object"

myString.valueOf();
> "I'm a string."

ज़्यादातर मामलों में, नतीजे के तौर पर जनरेट हुए ऑब्जेक्ट, उन वैल्यू की तरह काम करते हैं जिनका इस्तेमाल हमने किया है उन्हें परिभाषित किया जा सकता है. उदाहरण के लिए, भले ही आप new Number कंस्ट्रक्टर से ऐसा ऑब्जेक्ट मिलेगा जिसमें सभी मेथड और के गुण Number प्रोटोटाइप के हैं, तो आप गणितीय ऑपरेटरों का उपयोग ये ऑब्जेक्ट, नंबर लिटरल की तरह हैं:

const numberOne = new Number(1);
const numberTwo = new Number(2);

numberOne;
> Number { 1 }

typeof numberOne;
> "object"

numberTwo;
> Number { 2 }

typeof numberTwo;
> "object"

numberOne + numberTwo;
> 3

आपको इन कंस्ट्रक्टर का इस्तेमाल करने की बहुत ही कम ज़रूरत होगी, क्योंकि JavaScript, प्रोटोटाइप इनहेरिटेंस का मतलब है कि इनसे कोई फ़ायदा नहीं होता. बनाई जा रही है कंस्ट्रक्टर का इस्तेमाल करने वाले प्रिमिटिव से भी अनचाहे नतीजे मिल सकते हैं, क्योंकि नतीजा एक ऑब्जेक्ट है, न कि कोई सामान्य लिटरल:

let stringLiteral = "String literal."

typeof stringLiteral;
> "string"

let stringObject = new String( "String object." );

stringObject
> "object"

इसकी वजह से, तुलना करने वाले सख्त ऑपरेटर के इस्तेमाल में परेशानी आ सकती है:

const myStringLiteral = "My string";
const myStringObject = new String( "My string" );

myStringLiteral === "My string";
> true

myStringObject === "My string";
> false

अपने-आप सेमीकोलन शामिल करना (ASI)

स्क्रिप्ट पार्स करते समय, JavaScript अनुवादक जिन जगहों पर मौजूद डेटा को मिटाया नहीं गया है उन्हें ठीक करने के लिए, ऑटोमैटिक सेमीकोलन इंसर्शन (एएसआई) करना सेमीकोलन. अगर JavaScript पार्सर को कोई ऐसा टोकन मिलता है जिसकी अनुमति नहीं है, तो सिंटैक्स की संभावित गड़बड़ी को ठीक करने के लिए, उस टोकन से पहले सेमीकोलन जोड़ने की कोशिश करता है, जब तक कि इनमें से एक या ज़्यादा शर्तें सही हों:

  • उस टोकन को पिछले टोकन से अलग करने के लिए, लाइन ब्रेक का इस्तेमाल किया जाता है.
  • वह टोकन } है.
  • पिछला टोकन ) है और डाला गया सेमीकोलन आखिर होगा do...while स्टेटमेंट का सेमीकोलन.

ज़्यादा जानकारी के लिए, एएसआई के नियम देखें.

उदाहरण के लिए, नीचे दिए गए स्टेटमेंट के बाद सेमीकॉलन छोड़ने से, ASI की वजह से सिंटैक्स में गड़बड़ी है:

const myVariable = 2
myVariable + 3
> 5

हालांकि, एएसआई एक ही लाइन में कई स्टेटमेंट शामिल नहीं कर सकता. अगर आपको एक ही पंक्ति पर एक से ज़्यादा कथन लिखें, और उन्हें एक-दूसरे से अलग करें सेमीकोलन:

const myVariable = 2 myVariable + 3
> Uncaught SyntaxError: unexpected token: identifier

const myVariable = 2; myVariable + 3;
> 5

एएसआई, गड़बड़ी को ठीक करने की कोशिश है. यह शब्दों को बेहतर बनाने की सुविधा नहीं है उसे JavaScript में बदला जा सकता है. जहां सही हो वहां सेमीकॉलन का इस्तेमाल करें, ताकि आप पर भरोसा न करें ताकि उस पर सही कोड बनाया जा सके.

स्ट्रिक्ट मोड

JavaScript को लिखने के तरीके को कंट्रोल करने वाले मानक, काफ़ी आगे तक बढ़ गए हैं किसी भी विषय पर विचार किया जा सकता है. इसमें होने वाला हर नया बदलाव JavaScript के काम करने के तरीके के हिसाब से, पुरानी वेबसाइटों में गड़बड़ियां नहीं होनी चाहिए.

ES5 की मदद से, लंबे समय से चली आ रही कुछ समस्याओं का पता लगाया जा सकता है. इनमें, JavaScript सिमेंटिक्स की समस्याएं शामिल हैं "स्ट्रिक्ट मोड" लागू करके, मौजूदा तरीकों का उल्लंघन नहीं किया जा सकता. ऑप्ट-आउट करने का तरीका भाषा नियमों के और पाबंदी वाले सेट का इस्तेमाल करके, पूरी स्क्रिप्ट या अलग-अलग फ़ंक्शन का इस्तेमाल करना होगा. स्ट्रिक्ट मोड चालू करने के लिए, स्ट्रिंग लिटरल का इस्तेमाल करें स्क्रिप्ट की पहली लाइन पर, "use strict" के बाद सेमीकोलन या फ़ंक्शन:

"use strict";
function myFunction() {
  "use strict";
}

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

(function() {
  mySloppyGlobal = true;
}());

mySloppyGlobal;
> true

मॉडर्न JavaScript रनटाइम बिना किसी जोखिम के इस काम को ठीक नहीं कर सकते उस कॉन्टेंट पर भरोसा करने वाली किसी वेबसाइट पर मौजूद कॉन्टेंट को, गलती से या जान-बूझकर बंद किया जा सकता है. इसके बजाय, मॉडर्न JavaScript, डेवलपर को सख्ती से लागू होने से रोकता है. नए काम के लिए मोड मुहैया कराएं और नई भाषा की सुविधाएं, जो लागू किए गए लेगसी वर्शन पर असर नहीं डालेंगी:

(function() {
    "use strict";
    mySloppyGlobal = true;
}());
> Uncaught ReferenceError: assignment to undeclared variable mySloppyGlobal

आपको "use strict" को स्ट्रिंग लिटरल. टेंप्लेट का इस्तेमाल (use strict) काम नहीं करेगा. आपको किसी भी समय "use strict" को शामिल करने से पहले में तय किया जा सकता है. अगर ऐसा नहीं है, तो अनुवादक उसे अनदेखा कर देता है.

(function() {
    "use strict";
    let myVariable = "String.";
    console.log( myVariable );
    sloppyGlobal = true;
}());
> "String."
> Uncaught ReferenceError: assignment to undeclared variable sloppyGlobal

(function() {
    let myVariable = "String.";
    "use strict";
    console.log( myVariable );
    sloppyGlobal = true;
}());
> "String." // Because there was code prior to "use strict", this variable still pollutes the global scope

रेफ़रंस के हिसाब से, वैल्यू के हिसाब से

किसी भी वैरिएबल के साथ-साथ किसी ऑब्जेक्ट की प्रॉपर्टी, फ़ंक्शन पैरामीटर और एलिमेंट अरे, set या मैप में कोई भी प्रिमिटिव हो सकता है वैल्यू या रेफ़रंस वैल्यू.

जब किसी प्रिमिटिव वैल्यू को एक वैरिएबल से दूसरे वैरिएबल में असाइन किया जाता है, तो JavaScript इंजन उस वैल्यू की एक कॉपी बनाता है और उसे वैरिएबल को असाइन करता है.

जब किसी ऑब्जेक्ट को (क्लास इंस्टेंस, अरे, और फ़ंक्शन) वैरिएबल में, उस ऑब्जेक्ट की नई कॉपी बनाने के बजाय, वैरिएबल में में ऑब्जेक्ट की सेव की गई जगह के बारे में जानकारी होती है. इस वजह से, किसी वैरिएबल से रेफ़र किया गया ऑब्जेक्ट, रेफ़र किए जा रहे ऑब्जेक्ट में बदलाव करता है उस वैरिएबल में मौजूद वैल्यू. उदाहरण के लिए, अगर किसी नए ऐसा वैरिएबल जिसमें एक ऑब्जेक्ट संदर्भ वाला वैरिएबल हो, तो नए वैरिएबल जोड़ने के लिए, प्रॉपर्टी और उसकी वैल्यू जोड़ दी जाती हैं ओरिजनल ऑब्जेक्ट को लिंक करने के लिए:

const myObject = {};
const myObjectReference = myObject;

myObjectReference.myProperty = true;

myObject;
> Object { myProperty: true }

यह सिर्फ़ वस्तुओं में बदलाव करने के लिए ही नहीं, बल्कि सख्त कार्रवाई करने में भी ज़रूरी है की तुलना करें, क्योंकि ऑब्जेक्ट के बीच सख्त समानता में दोनों वैरिएबल की ज़रूरत होती है true की वैल्यू निकालने के लिए, उसी ऑब्जेक्ट का रेफ़रंस दें. इनका रेफ़रंस नहीं दिया जा सकता अलग-अलग ऑब्जेक्ट, भले ही वे संरचनात्मक रूप से एक जैसे हों:

const myObject = {};
const myReferencedObject = myObject;
const myNewObject = {};

myObject === myNewObject;
> false

myObject === myReferencedObject;
> true

मेमोरी का बंटवारा

JavaScript में, मेमोरी अपने-आप मैनेज होने की सुविधा इस्तेमाल होती है. इसका मतलब है कि मेमोरी की ज़रूरत नहीं होती उन्हें डेवलपमेंट के दौरान साफ़ तौर पर बांटा या हटाया जा सकता है. हालांकि देखें, इसमें, मेमोरी मैनेज करने के अलग-अलग तरीके इस मॉड्यूल के दायरे में, मेमोरी के बंटवारे के तरीके को समझना फ़ायदेमंद हो सकता है संदर्भ मान के साथ काम करने का संदर्भ होना चाहिए.

दो "क्षेत्र" हैं मेमोरी में: "स्टैक" और "हीप". स्टैक स्टोर स्टैटिक डेटा—प्रीमिटिव वैल्यू और ऑब्जेक्ट के रेफ़रंस—क्योंकि इस डेटा को स्टोर करने के लिए तय जगह को स्क्रिप्ट चलती है. हीप में वे ऑब्जेक्ट सेव होते हैं जिनके लिए डाइनैमिक तौर पर तय की गई जगह की ज़रूरत होती है क्योंकि एक्ज़िक्यूशन के दौरान उनका साइज़ बदल सकता है. मेमोरी को एक प्रोसेस से खाली किया जाता है जिसे "कचरा इकट्ठा करना" कहते हैं, जिससे बिना रेफ़रंस वाले ऑब्जेक्ट हटा दिए जाते हैं मेमोरी.

मुख्य थ्रेड

JavaScript मूल रूप से सिंगल-थ्रेड वाली भाषा होती है, जिसमें "सिंक्रोनस" होती है. एक्ज़ीक्यूशन मॉडल का मतलब है कि यह सिर्फ़ एक टास्क लागू कर सकता है एक समय में. इस क्रम में लागू होने वाले कॉन्टेक्स्ट को मुख्य थ्रेड कहा जाता है.

मुख्य थ्रेड को अन्य ब्राउज़र टास्क के ज़रिए शेयर किया जाता है, जैसे कि एचटीएमएल को पार्स करना, पेज के हिस्सों को रेंडर और फिर से रेंडर करना, सीएसएस ऐनिमेशन चलाना, और आसान (जैसे, टेक्स्ट हाइलाइट करना) से लेकर, अन्य जटिल (जैसे, फ़ॉर्म एलिमेंट के साथ इंटरैक्ट करना). ब्राउज़र वेंडर को मिला है मुख्य थ्रेड से किए गए टास्क को ऑप्टिमाइज़ करता है, लेकिन यह ज़्यादा मुश्किल है स्क्रिप्ट अब भी मुख्य थ्रेड के बहुत ज़्यादा संसाधनों का इस्तेमाल कर सकती हैं. पेज परफ़ॉर्मेंस.

कुछ टास्क यहां किए जा सकते हैं बैकग्राउंड थ्रेड जिन्हें वेब वर्कर कहा जाता है, कुछ सीमाओं के साथ:

  • वर्कर थ्रेड सिर्फ़ स्टैंडअलोन JavaScript फ़ाइलों पर काम कर सकते हैं.
  • उन्होंने ब्राउज़र विंडो और यूज़र इंटरफ़ेस (यूआई) का ऐक्सेस बहुत कम कर दिया है या ऐक्सेस नहीं है.
  • वे मुख्य थ्रेड के साथ सीमित तौर पर बातचीत कर पाते हैं.

इन सीमाओं की वजह से, ये टास्क ऐसे काम करते हैं जिनमें ज़्यादा मेहनत और फ़ोकस की ज़रूरत होती है. ऐसा न होने पर, मुख्य थ्रेड में शामिल हो सकती है.

कॉल स्टैक

"एक्ज़िक्यूशन कॉन्टेक्स्ट" को मैनेज करने के लिए इस्तेमाल किया जाने वाला डेटा स्ट्रक्चर—कोड को सक्रिय तौर पर एक्ज़ीक्यूट किया जाता है—यह कॉल स्टैक नाम की सूची होती है (अक्सर सिर्फ़ "स्टैक") का इस्तेमाल करें. पहली बार स्क्रिप्ट चलाने पर, JavaScript इंटरप्रेटर एक "वैश्विक एक्ज़ीक्यूशन कॉन्टेक्स्ट" बनाता है और उसे कॉल स्टैक में पुश करता है, वैश्विक संदर्भ के दौरान, एक-एक करके लागू किए जाने वाले स्टेटमेंट नीचे. जब अनुवादक ग्लोबल कॉन्टेक्स्ट के तौर पर सेट किया जाता है, तो यह "फ़ंक्शन को लागू करने का कॉन्टेक्स्ट" दिखाता है उस कॉल के लिए स्टैक में सबसे ऊपर, ग्लोबल एक्ज़ीक्यूशन कॉन्टेक्स्ट को रोकता है, और फ़ंक्शन को एक्ज़ीक्यूट करता है एक्ज़ीक्यूट किया जा सकता है.

जब भी किसी फ़ंक्शन को कॉल किया जाता है, तो उस कॉल के लिए फ़ंक्शन एक्ज़ीक्यूट होने का कॉन्टेक्स्ट यह होता है स्टैक को सबसे ऊपर पुश किया जाता है, जो मौजूदा एक्ज़ीक्यूशन कॉन्टेक्स्ट के ठीक ऊपर होता है. कॉल स्टैक "फ़र्स्ट इन, फ़र्स्ट आउट" पर काम करता है आधार है, जिसका मतलब है कि सबसे हाल ही का फ़ंक्शन कॉल, जो स्टैक में सबसे ज़्यादा है हल हो जाने तक. यह फ़ंक्शन पूरा होने के बाद, अनुवादक उसे हटा देता है को एक्ज़ीक्यूट करने की कोशिश की. फिर से स्टैक में सबसे ऊंचा आइटम बन जाता है और एक्ज़ीक्यूशन को फिर से शुरू कर देता है.

एक्ज़ीक्यूशन के ये कॉन्टेक्स्ट, लागू होने के लिए ज़रूरी सभी वैल्यू को कैप्चर करते हैं. वे वे वैरिएबल और फ़ंक्शन भी सेट कर सकते हैं जो अपने मूल संदर्भ के आधार पर फ़ंक्शन का इस्तेमाल करता है और फ़ंक्शन के संदर्भ में this कीवर्ड.

इवेंट लूप और कॉलबैक लिस्ट

क्रम से चलने का मतलब है कि एसिंक्रोनस टास्क जिनमें कॉलबैक शामिल है किसी सर्वर से डेटा फ़ेच करने, उपयोगकर्ता के इंटरैक्शन को जवाब देने जैसे फ़ंक्शन या setTimeout या setInterval के साथ सेट किए गए टाइमर का इंतज़ार किया जा रहा हो, तो ब्लॉक हो जाएगा मुख्य थ्रेड को तब तक नहीं सुनें, जब तक कि टास्क पूरा नहीं हो जाता या अचानक से एक्ज़ीक्यूशन का मौजूदा कॉन्टेक्स्ट, जब कॉलबैक फ़ंक्शन को एक्ज़ीक्यूट किया जाता है को स्टैक में जोड़ा गया है. इसे ठीक करने के लिए, JavaScript एसिंक्रोनस टास्क को मैनेज करता है इवेंट-ड्रिवन "कॉनमुद्रा मॉडल" का इस्तेमाल करके जो "इवेंट लूप" से बना होता है और "कॉलबैक सूची" (इसे कभी-कभी "मैसेज की सूची" भी कहा जाता है).

जब मुख्य थ्रेड पर कोई एसिंक्रोनस टास्क पूरा होता है, तो कॉलबैक फ़ंक्शन को एक्ज़ीक्यूट करने के कॉन्टेक्स्ट को कॉलबैक लिस्ट में रखा जाता है, न कि कॉल स्टैक की सुविधा मिलती है. इवेंट लूप एक ऐसा पैटर्न होता है जिसे कभी-कभी रिऐक्टर का इस्तेमाल करता है, जो लगातार कॉल स्टैक और कॉलबैक क्यू की स्थिति का पोल करता है. अगर इसमें टास्क हैं कॉलबैक लिस्ट और इवेंट लूप से पता चलता है कि कॉल स्टैक खाली है. कॉलबैक सूची के टास्क को एक बार में एक स्टैक में पुश किया जाता है लागू किया गया.