javascript - सरण - जावास्क्रिप्ट में 'नया' कीवर्ड क्या है?




जावास्क्रिप्ट सवाल (9)

जब पहली बार इसका सामना करना पड़ता है, तो जावास्क्रिप्ट में new कीवर्ड काफी भ्रमित हो सकता है, क्योंकि लोग सोचते हैं कि जावास्क्रिप्ट एक ऑब्जेक्ट उन्मुख प्रोग्रामिंग भाषा नहीं है।

  • यह क्या है?
  • यह किस समस्या का समाधान करता है?
  • यह कब उचित है और कब नहीं?

https://code.i-harness.com


तो शायद यह वस्तु के उदाहरण बनाने के लिए नहीं है

इसका उपयोग बिल्कुल इसके लिए किया जाता है। आप इस तरह एक फ़ंक्शन कन्स्ट्रक्टर को परिभाषित करते हैं:

function Person(name) {
    this.name = name;
}

var john = new Person('John');

हालांकि .prototype के अतिरिक्त लाभ यह है कि आप .prototype संपत्ति के साथ विस्तार कर सकते हैं, इसलिए हम कुछ ऐसा कर सकते हैं ...

Person.prototype.getName = function() { return this.name; }

इस कन्स्ट्रक्टर से बनाए गए सभी ऑब्जेक्ट्स के पास अब प्रोटोटाइप श्रृंखला की getName कारण getName होगा।


शुरुआत के लिए इसे बेहतर समझने के लिए

कंसोल में निम्न कोड आज़माएं।

function Foo() { 
    return this; 
}

var a = Foo();       //returns window object
var b = new Foo();   //returns empty object of foo

console.log(a instanceof Window);  // true
console.log(a instanceof Foo);     // false

console.log(b instanceof Window);  // false
console.log(b instanceof Foo);     // true

अब आप समुदाय विकी जवाब पढ़ सकते हैं :)


खैर जावास्क्रिप्ट प्रति सी मंच से मंच तक काफी भिन्न हो सकता है क्योंकि यह हमेशा मूल विनिर्देश EcmaScript का कार्यान्वयन होता है।

किसी भी मामले में, स्वतंत्र रूप से कार्यान्वित करने के लिए सभी जावास्क्रिप्ट कार्यान्वयन जो एक्मास्क्रिप्ट विनिर्देश का पालन करते हैं, आपको ऑब्जेक्ट ओरिएंटेड भाषा देंगे। ईएस मानक के अनुसार:

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

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

एक्मास्क्रिप्ट में हम कक्षाओं का उपयोग नहीं करते हैं, क्योंकि आप चश्मे से पढ़ सकते हैं:

ईसीएमएस्क्रिप्ट सी ++, स्मॉलटॉक या जावा जैसे वर्गों का उपयोग नहीं करता है। इसके बजाय ऑब्जेक्ट्स को शाब्दिक नोटेशन के माध्यम से या रचनाकारों के माध्यम से विभिन्न तरीकों से बनाया जा सकता है जो ऑब्जेक्ट्स बनाते हैं और उसके बाद कोड को निष्पादित करते हैं जो उनके गुणों के प्रारंभिक मूल्यों को निर्दिष्ट करके उनमें से सभी या भाग को प्रारंभ करता है। प्रत्येक कन्स्ट्रक्टर एक ऐसा फ़ंक्शन होता है जिसमें नाम की एक संपत्ति होती है - प्रोटोटाइप ‖ जिसका उपयोग प्रोटोटाइप-आधारित विरासत और साझा गुणों को लागू करने के लिए किया जाता है। ऑब्जेक्ट्स द्वारा बनाए जाते हैं
नए अभिव्यक्तियों में रचनाकारों का उपयोग करना; उदाहरण के लिए, नई तिथि (200 9, 11) एक नई तिथि वस्तु बनाता है। नए इस्तेमाल किए बिना एक कन्स्ट्रक्टर को आमंत्रित करने के परिणामस्वरूप कन्स्ट्रक्टर पर निर्भर करता है। उदाहरण के लिए, दिनांक () किसी ऑब्जेक्ट की बजाय वर्तमान दिनांक और समय का स्ट्रिंग प्रस्तुति उत्पन्न करता है।


जावास्क्रिप्ट एक ऑब्जेक्ट उन्मुख प्रोग्रामिंग भाषा है और इसका उपयोग उदाहरण बनाने के लिए बिल्कुल किया जाता है। यह वर्ग-आधारित के बजाय प्रोटोटाइप-आधारित है, लेकिन इसका मतलब यह नहीं है कि यह ऑब्जेक्ट उन्मुख नहीं है।


डैनियल हावर्ड के जवाब के अलावा, यहां new क्या है (या कम से कम ऐसा लगता है):

function New(func) {
    var res = {};
    if (func.prototype !== null) {
        res.__proto__ = func.prototype;
    }
    var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
    if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
        return ret;
    }
    return res;
}

जबकि

var obj = New(A, 1, 2);

के बराबर है

var obj = new A(1, 2);

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

केस I :

var Foo = function(){
  this.A = 1; 
  this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1

ऊपर Foo द्वारा इंगित अज्ञात फ़ंक्शन को कॉल करने का एक सादा मामला है। जब आप इस फ़ंक्शन को कॉल करते हैं तो यह undefined । चूंकि कोई स्पष्ट रिटर्न स्टेटमेंट नहीं है, इसलिए जावास्क्रिप्ट दुभाषिया मजबूती से एक return undefined; समारोह के अंत में बयान। यहां विंडो आविष्कार वस्तु है (प्रासंगिक this ) जो नई A और B गुण प्राप्त करती है।

प्रकरण II :

var Foo = function(){
  this.A = 1;
  this.B = 2;
};
var bar = new Foo();
console.log(bar()); //illegal isn't pointing to a function but an object
console.log(bar.A); //prints 1

यहां new कीवर्ड को देखकर जावास्क्रिप्ट दुभाषिया एक नई वस्तु बनाता है जो Foo द्वारा इंगित अज्ञात फ़ंक्शन के आमंत्रण ऑब्जेक्ट (प्रासंगिक) के रूप में कार्य करता है। इस मामले में A और B नव निर्मित वस्तु (विंडो ऑब्जेक्ट के स्थान पर) पर गुण बन जाते हैं। चूंकि आपके पास कोई स्पष्ट रिटर्न स्टेटमेंट नहीं है, इसलिए जावास्क्रिप्ट दुभाषिया new कीवर्ड के उपयोग के कारण बनाए गए नए ऑब्जेक्ट को वापस करने के लिए मजबूती से एक रिटर्न स्टेटमेंट डालता है।

प्रकरण III :

var Foo = function(){
  this.A = 1;
  this.B = 2;
  return {C:20,D:30}; 
};
var bar = new Foo();
console.log(bar.C);//prints 20
console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.

यहां फिर से new कीवर्ड देखने वाला जावास्क्रिप्ट दुभाषिया एक नई वस्तु बनाता है जो Foo द्वारा इंगित अज्ञात फ़ंक्शन के आमंत्रण ऑब्जेक्ट (प्रासंगिक) के रूप में कार्य करता है। फिर, A और B नव निर्मित वस्तु पर गुण बन जाते हैं। लेकिन इस बार आपके पास एक स्पष्ट वापसी कथन है, इसलिए जावास्क्रिप्ट दुभाषिया अपने आप से कुछ भी नहीं करेगा।

तीसरे मामले में ध्यान देने योग्य बात यह है कि new रडार के कारण बनाया गया ऑब्जेक्ट आपके रडार से खो गया है। bar वास्तव में एक पूरी तरह से अलग वस्तु को इंगित कर रहा है जो कि new कीवर्ड के कारण जावास्क्रिप्ट दुभाषिया नहीं बनाया गया है।


यह 5 चीजें करता है:

  1. यह एक नई वस्तु बनाता है। इस वस्तु का प्रकार बस वस्तु है
  2. यह इस नए ऑब्जेक्ट के आंतरिक, अप्राप्य, [[प्रोटोटाइप]] (यानी __proto__ ) प्रॉपर्टी को कन्स्ट्रक्टर फ़ंक्शन के बाहरी, सुलभ, प्रोटोटाइप ऑब्जेक्ट (प्रत्येक फ़ंक्शन ऑब्जेक्ट में स्वचालित रूप से प्रोटोटाइप प्रॉपर्टी) सेट करता है।
  3. यह this परिवर्तनीय बिंदु को नव निर्मित वस्तु को बनाता है।
  4. जब भी इसका उल्लेख किया जाता है तो नव निर्मित ऑब्जेक्ट का उपयोग करके यह कन्स्ट्रक्टर फ़ंक्शन निष्पादित करता है।
  5. यह नव निर्मित ऑब्जेक्ट देता है, जब तक कि कन्स्ट्रक्टर फ़ंक्शन एक गैर- null ऑब्जेक्ट संदर्भ देता है। इस मामले में, उस ऑब्जेक्ट संदर्भ को बदले में वापस कर दिया जाता है।

नोट: कन्स्ट्रक्टर फ़ंक्शन new कीवर्ड के बाद फ़ंक्शन को संदर्भित करता है, जैसा कि

new ConstructorFunction(arg1, arg2)

एक बार ऐसा करने के बाद, यदि नई ऑब्जेक्ट की एक अपरिभाषित संपत्ति का अनुरोध किया जाता है, तो स्क्रिप्ट इसके बजाय संपत्ति के लिए ऑब्जेक्ट की [[प्रोटोटाइप]] ऑब्जेक्ट की जांच करेगी। इस प्रकार आप जावास्क्रिप्ट में पारंपरिक वर्ग विरासत के समान कुछ प्राप्त कर सकते हैं।

इसके बारे में सबसे कठिन हिस्सा बिंदु संख्या 2 है। प्रत्येक ऑब्जेक्ट (फ़ंक्शंस समेत) में यह आंतरिक संपत्ति है [[प्रोटोटाइप]] । इसे केवल ऑब्जेक्ट निर्माण समय पर, ऑब्जेक्ट.क्रेट के साथ, या शाब्दिक (फ़ंक्शंस.प्रोटोटाइप पर डिफ़ॉल्ट फ़ंक्शंस, संख्याओं के लिए संख्या। प्रोटीोटाइप इत्यादि) के आधार पर सेट किया जा सकता है। इसे केवल Object.getPrototypeOf (someObject) के साथ पढ़ा जा सकता है। इस मूल्य को सेट या पढ़ने का कोई और तरीका नहीं है

छिपे हुए [[प्रोटोटाइप]] संपत्ति के अतिरिक्त कार्य, प्रोटोटाइप नामक एक संपत्ति भी है, और यह है कि आप जो वस्तुएं बनाते हैं, उनके लिए विरासत गुण और विधियां प्रदान करने के लिए आप इसका उपयोग कर सकते हैं और संशोधित कर सकते हैं।

यहाँ एक उदाहरण है:

ObjMaker = function() {this.a = 'first';};
// ObjMaker is just a function, there's nothing special about it that makes 
// it a constructor.

ObjMaker.prototype.b = 'second';
// like all functions, ObjMaker has an accessible prototype property that 
// we can alter. I just added a property called 'b' to it. Like 
// all objects, ObjMaker also has an inaccessible [[prototype]] property
// that we can't do anything with

obj1 = new ObjMaker();
// 3 things just happened.
// A new, empty object was created called obj1.  At first obj1 was the same
// as {}. The [[prototype]] property of obj1 was then set to the current
// object value of the ObjMaker.prototype (if ObjMaker.prototype is later
// assigned a new object value, obj1's [[prototype]] will not change, but you
// can alter the properties of ObjMaker.prototype to add to both the
// prototype and [[prototype]]). The ObjMaker function was executed, with
// obj1 in place of this... so obj1.a was set to 'first'.

obj1.a;
// returns 'first'
obj1.b;
// obj1 doesn't have a property called 'b', so JavaScript checks 
// its [[prototype]]. Its [[prototype]] is the same as ObjMaker.prototype
// ObjMaker.prototype has a property called 'b' with value 'second'
// returns 'second'

यह वर्ग विरासत की तरह है क्योंकि अब, आप जो भी ऑब्जेक्ट्स new ObjMaker() का उपयोग करते हैं, वे भी 'बी' संपत्ति विरासत में पाएंगे।

यदि आप सबक्लास की तरह कुछ चाहते हैं, तो आप यह करते हैं:

SubObjMaker = function () {};
SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated!
// Because we used 'new', the [[prototype]] property of SubObjMaker.prototype
// is now set to the object value of ObjMaker.prototype.
// The modern way to do this is with Object.create(), which was added in ECMAScript 5:
// SubObjMaker.prototype = Object.create(ObjMaker.prototype);

SubObjMaker.prototype.c = 'third';  
obj2 = new SubObjMaker();
// [[prototype]] property of obj2 is now set to SubObjMaker.prototype
// Remember that the [[prototype]] property of SubObjMaker.prototype
// is ObjMaker.prototype. So now obj2 has a prototype chain!
// obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype

obj2.c;
// returns 'third', from SubObjMaker.prototype

obj2.b;
// returns 'second', from ObjMaker.prototype

obj2.a;
// returns 'first', from SubObjMaker.prototype, because SubObjMaker.prototype 
// was created with the ObjMaker function, which assigned a for us

आखिरकार इस पृष्ठ को ढूंढने से पहले मैंने इस विषय पर बकवास का एक टन पढ़ा, जहां इसे अच्छे आरेखों के साथ बहुत अच्छी तरह से समझाया गया है।


new कीवर्ड उस संदर्भ को बदलता है जिसके तहत फ़ंक्शन चलाया जा रहा है और उस संदर्भ में पॉइंटर लौटाता है।

जब आप new कीवर्ड का उपयोग नहीं करते हैं, तो संदर्भ जिसके तहत Vehicle() रन चलता है वही संदर्भ है जिससे आप Vehicle समारोह को बुला रहे हैं। this कीवर्ड एक ही संदर्भ का संदर्भ देगा। जब आप new Vehicle() उपयोग करते हैं, तो एक नया संदर्भ बनाया जाता है, इसलिए फ़ंक्शन के अंदर this कीवर्ड नए संदर्भ को संदर्भित करता है। बदले में आपको क्या मिलता है नव निर्मित संदर्भ है।


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

obj = new Element();




new-operator