क्या जावास्क्रिप्ट पास-दर-संदर्भ या पास-पास-मूल्य भाषा है?

Feb 06 2009

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

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

जवाब

1665 deworde Sep 04 2010 at 00:17

यह जावास्क्रिप्ट में दिलचस्प है। इस उदाहरण पर विचार करें:

function changeStuff(a, b, c)
{
  a = a * 10;
  b.item = "changed";
  c = {item: "changed"};
}

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};

changeStuff(num, obj1, obj2);

console.log(num);
console.log(obj1.item);
console.log(obj2.item);

यह उत्पादन का उत्पादन करता है:

10
changed
unchanged
  • यदि obj1एक संदर्भ नहीं था, तो फ़ंक्शन obj1.itemके obj1बाहर पर परिवर्तन का कोई प्रभाव नहीं होगा ।
  • यदि तर्क एक उचित संदर्भ होता, तो सब कुछ बदल जाता। numहोगा 100, और obj2.itemपढ़ेगा "changed"

इसके बजाय, स्थिति यह है कि आइटम को पारित मूल्य से पारित किया जाता है। लेकिन मूल्य द्वारा पारित किया गया आइटम स्वयं एक संदर्भ है। तकनीकी रूप से, इसे कॉल-बाय-शेयरिंग कहा जाता है ।

व्यावहारिक रूप से, इसका मतलब है कि यदि आप पैरामीटर को (जैसा कि) numऔर अपने आप को बदलते हैं obj2, तो वह उस आइटम को प्रभावित नहीं करेगा जो पैरामीटर में खिलाया गया था। लेकिन अगर आप पैरामीटर के इंटर्नशिप को बदलते हैं , तो यह वापस ऊपर (जैसे के साथ obj1) प्रचार करेगा ।

493 TimGoodman Mar 15 2011 at 23:38

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

उदाहरण:

function changeObject(x) {
  x = { member: "bar" };
  console.log("in changeObject: " + x.member);
}

function changeMember(x) {
  x.member = "bar";
  console.log("in changeMember: " + x.member);
}

var x = { member: "foo" };

console.log("before changeObject: " + x.member);
changeObject(x);
console.log("after changeObject: " + x.member); /* change did not persist */

console.log("before changeMember: " + x.member);
changeMember(x);
console.log("after changeMember: " + x.member); /* change persists */

आउटपुट:

before changeObject: foo
in changeObject: bar
after changeObject: foo

before changeMember: foo
in changeMember: bar
after changeMember: bar
156 Shog9 Feb 06 2009 at 04:37

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

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

115 RayPerea Aug 04 2014 at 18:06

मेरे दो सेंट ... यह मुझे समझने का तरीका है। (अगर मैं गलत हूं तो मुझे सुधारने के लिए स्वतंत्र महसूस करें)

यह मूल्य / संदर्भ द्वारा आप के बारे में सब कुछ जानने का समय है।

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

ठीक है, मुझे समझाने की पूरी कोशिश करें कि मेरा क्या मतलब है। मान लीजिए कि आपके पास कुछ वस्तुएं हैं।

var object1 = {};
var object2 = {};

हमने जो किया है वह "असाइनमेंट" है ... हमने चर "ऑब्जेक्ट 1" और "ऑब्जेक्ट 2" के लिए 2 अलग-अलग खाली वस्तुओं को सौंपा है।

अब, मान लें कि हम ऑब्जेक्ट 1 को बेहतर पसंद करते हैं ... इसलिए, हम एक नया वेरिएबल "असाइन" करते हैं।

var favoriteObject = object1;

अगला, जो भी कारण से, हम तय करते हैं कि हम ऑब्जेक्ट 2 को बेहतर पसंद करते हैं। इसलिए, हम थोड़ा पुन: असाइनमेंट करते हैं।

favoriteObject = object2;

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

object2.name = 'Fred';
console.log(favoriteObject.name) // Logs Fred
favoriteObject.name = 'Joe';
console.log(object2.name); // Logs Joe

ठीक है, अब उदाहरण के लिए तार की तरह आदिमों को देखें

var string1 = 'Hello world';
var string2 = 'Goodbye world';

फिर, हम एक पसंदीदा चुनते हैं।

var favoriteString = string1;

हमारे पसंदीदा स्ट्रींग और स्ट्रिंग 1 चर दोनों को 'हैलो वर्ल्ड' में सौंपा गया है। अब, क्या होगा अगर हम अपनी पसंद को बदलना चाहते हैं ??? क्या होगा???

favoriteString = 'Hello everyone';
console.log(favoriteString); // Logs 'Hello everyone'
console.log(string1); // Logs 'Hello world'

उह ओह .... क्या हुआ है। हम स्ट्रिंग 1 को पसंदीदास्ट्रीमिंग में बदलकर बदल नहीं सकते ... क्यों ?? क्योंकि हमने अपना स्ट्रिंग ऑब्जेक्ट नहीं बदला । हम सब किया था "आरई ASSIGN" पसंदीदा स्ट्रिंग एक नया स्ट्रिंग के लिए चर । यह अनिवार्य रूप से इसे string1 से काट दिया गया। पिछले उदाहरण में, जब हमने अपनी वस्तु का नाम बदला, तो हमने कुछ भी निर्दिष्ट नहीं किया। (ठीक है, चर के लिए ही नहीं , ... हमने किया था, हालांकि, नाम संपत्ति को एक नए स्ट्रिंग में असाइन करें।) इसके बजाय, हमने उस वस्तु को उत्परिवर्तित किया जो 2 चर और अंतर्निहित वस्तुओं के बीच संबंध रखता है। (यहां तक कि अगर हम संशोधित करने या करना चाहता था उत्परिवर्तित स्ट्रिंग वस्तु ही है, हम नहीं कर सके, क्योंकि तार वास्तव में जावास्क्रिप्ट में अडिग हैं।)

अब, फ़ंक्शंस और पासिंग पैरामीटर पर .... जब आप किसी फ़ंक्शन को कॉल करते हैं, और एक पैरामीटर पास करते हैं, तो आप जो अनिवार्य रूप से कर रहे हैं वह एक नए चर के लिए "असाइनमेंट" है, और यह बिल्कुल उसी तरह काम करता है जैसे कि आपने असाइन किया है बराबर (=) चिह्न।

इन उदाहरणों को लें।

var myString = 'hello';

// Assign to a new variable (just like when you pass to a function)
var param1 = myString;
param1 = 'world'; // Re assignment

console.log(myString); // Logs 'hello'
console.log(param1);   // Logs 'world'

अब, एक ही बात है, लेकिन एक समारोह के साथ

function myFunc(param1) {
    param1 = 'world';

    console.log(param1);   // Logs 'world'
}

var myString = 'hello';
// Calls myFunc and assigns param1 to myString just like param1 = myString
myFunc(myString);

console.log(myString); // logs 'hello'

ठीक है, अब चलो कुछ उदाहरण देते हैं इसके बजाय वस्तुओं का उपयोग करते हैं ... पहला, फ़ंक्शन के बिना।

var myObject = {
    firstName: 'Joe',
    lastName: 'Smith'
};

// Assign to a new variable (just like when you pass to a function)
var otherObj = myObject;

// Let's mutate our object
otherObj.firstName = 'Sue'; // I guess Joe decided to be a girl

console.log(myObject.firstName); // Logs 'Sue'
console.log(otherObj.firstName); // Logs 'Sue'

// Now, let's reassign the variable
otherObj = {
    firstName: 'Jack',
    lastName: 'Frost'
};

// Now, otherObj and myObject are assigned to 2 very different objects
// And mutating one object has no influence on the other
console.log(myObject.firstName); // Logs 'Sue'
console.log(otherObj.firstName); // Logs 'Jack';

अब, एक ही बात है, लेकिन एक फ़ंक्शन कॉल के साथ

function myFunc(otherObj) {

    // Let's mutate our object
    otherObj.firstName = 'Sue';
    console.log(otherObj.firstName); // Logs 'Sue'

    // Now let's re-assign
    otherObj = {
        firstName: 'Jack',
        lastName: 'Frost'
    };
    console.log(otherObj.firstName); // Logs 'Jack'

    // Again, otherObj and myObject are assigned to 2 very different objects
    // And mutating one object doesn't magically mutate the other
}

var myObject = {
    firstName: 'Joe',
    lastName: 'Smith'
};

// Calls myFunc and assigns otherObj to myObject just like otherObj = myObject
myFunc(myObject);

console.log(myObject.firstName); // Logs 'Sue', just like before

ठीक है, यदि आप इस पूरी पोस्ट को पढ़ते हैं, तो शायद अब आपको बेहतर समझ है कि जावास्क्रिप्ट में फ़ंक्शन कैसे काम करते हैं। इससे कोई फर्क नहीं पड़ता कि क्या कुछ संदर्भ या मूल्य द्वारा पारित किया गया है ... क्या मामलों में असाइनमेंट बनाम म्यूटेशन है।

हर बार जब आप किसी फ़ंक्शन को एक चर पास करते हैं, तो आप पैरामीटर चर का नाम जो भी हो, "असाइन करना" है, जैसे कि यदि आपने बराबर (=) चिह्न का उपयोग किया है।

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

एकमात्र समय जो "चर को संशोधित करता है" एक अलग चर को प्रभावित करता है, जब अंतर्निहित वस्तु उत्परिवर्तित होती है (जिस स्थिति में आपने चर को संशोधित नहीं किया है, लेकिन वस्तु ही।

वस्तुओं और आदिमों के बीच अंतर करने का कोई मतलब नहीं है, क्योंकि यह उसी तरह से काम करता है जैसे कि आपके पास कोई फ़ंक्शन नहीं था और नए चर को असाइन करने के लिए समान चिह्न का उपयोग किया था।

एकमात्र गोचा तब होता है जब आप फ़ंक्शन में आने वाले चर का नाम फ़ंक्शन पैरामीटर के नाम के समान होता है। जब ऐसा होता है, तो आपको फ़ंक्शन के अंदर पैरामीटर का इलाज करना होगा जैसे कि यह फ़ंक्शन के लिए एक नया चर है (क्योंकि यह है)

function myFunc(myString) {
    // myString is private and does not affect the outer variable
    myString = 'hello';
}

var myString = 'test';
myString = myString; // Does nothing, myString is still 'test';

myFunc(myString);
console.log(myString); // Logs 'test'
75 geg Sep 26 2015 at 11:06

निम्नलिखित को धयान मे रखते हुए:

  1. चर स्मृति में मूल्यों के संकेत हैं ।
  2. एक चर को फिर से इंगित करना केवल एक नए मूल्य पर सूचक को इंगित करता है।
  3. एक चर को फिर से सौंपना अन्य चर को प्रभावित नहीं करेगा जो उसी वस्तु पर इंगित कर रहे थे

तो, "संदर्भ / मूल्य से गुजारें" के बारे में भूल जाओ , "संदर्भ / मूल्य से पारित" पर लटका न दें क्योंकि:

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

आपके प्रश्न का उत्तर देने के लिए: संकेत पारित किए जाते हैं।


// code
var obj = {
    name: 'Fred',
    num: 1
};

// illustration
               'Fred'
              /
             /
(obj) ---- {}
             \
              \
               1


// code
obj.name = 'George';


// illustration
                 'Fred'


(obj) ---- {} ----- 'George'
             \
              \
               1


// code
obj = {};

// illustration
                 'Fred'


(obj)      {} ----- 'George'
  |          \
  |           \
 { }            1


// code
var obj = {
    text: 'Hello world!'
};

/* function parameters get their own pointer to 
 * the arguments that are passed in, just like any other variable */
someFunc(obj);


// illustration
(caller scope)        (someFunc scope)
           \             /
            \           /
             \         /
              \       /
               \     /
                 { }
                  |
                  |
                  |
            'Hello world'

कुछ अंतिम टिप्पणियां:

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


var a = [1,2];
var b = a;

a = [];
console.log(b); // [1,2]
// doesn't work because `b` is still pointing at the original array
24 user779764 Jun 03 2011 at 06:04

किसी फ़ंक्शन के बाहर की वस्तु को फ़ंक्शन में बाहरी वस्तु का संदर्भ देकर पारित किया जाता है।

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

22 PhilMander Feb 13 2015 at 18:00

इसे ऐसे समझें: यह हमेशा मूल्य से गुजरता है। हालाँकि, किसी वस्तु का मूल्य स्वयं वस्तु नहीं है, बल्कि उस वस्तु का संदर्भ है।

यहाँ एक उदाहरण है, एक संख्या (एक आदिम प्रकार) पास करना

function changePrimitive(val) {
    // At this point there are two '10's in memory.
    // Changing one won't affect the other
    val = val * 10;
}
var x = 10;
changePrimitive(x);
// x === 10

किसी वस्तु के साथ इसे दोहराने से विभिन्न परिणाम मिलते हैं:

function changeObject(obj) {
    // At this point there are two references (x and obj) in memory,
    // but these both point to the same object.
    // changing the object will change the underlying object that
    // x and obj both hold a reference to.
    obj.val = obj.val * 10;
}
var x = { val: 10 };
changeObject(x);
// x === { val: 100 }

एक और उदाहरण:

function changeObject(obj) {
    // Again there are two references (x and obj) in memory,
    // these both point to the same object.
    // now we create a completely new object and assign it.
    // obj's reference now points to the new object.
    // x's reference doesn't change.
    obj = { val: 100 };
}
var x = { val: 10 };
changeObject(x);
// x === { val: 10}
20 igor May 13 2011 at 05:20

मूल्य और संदर्भ द्वारा प्रतिलिपि बनाने, पास करने और तुलना करने के बारे में एक बहुत विस्तृत विवरण "जावास्क्रिप्ट: द डेफिनिटिव गाइड" पुस्तक के इस अध्याय में है ।

इससे पहले कि हम संदर्भ द्वारा वस्तुओं और सरणियों में हेरफेर करने के विषय को छोड़ दें, हमें नामकरण के एक बिंदु को स्पष्ट करने की आवश्यकता है।

वाक्यांश "संदर्भ द्वारा पास" के कई अर्थ हो सकते हैं। कुछ पाठकों के लिए, वाक्यांश एक फ़ंक्शन इनवोकेशन तकनीक को संदर्भित करता है जो एक फ़ंक्शन को अपने तर्कों के लिए नए मूल्यों को असाइन करने और फ़ंक्शन के बाहर उन संशोधित मूल्यों को देखने की अनुमति देता है। इस पुस्तक में इस शब्द का उपयोग जिस तरह से किया गया है, वह नहीं है।

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

इस शब्द के दूसरे अर्थ से परिचित पाठक यह कहना पसंद कर सकते हैं कि ऑब्जेक्ट और सरणियाँ मान द्वारा पारित किए जाते हैं, लेकिन जो मान पास किया जाता है वह वास्तव में ऑब्जेक्ट के बजाय एक संदर्भ है।

18 MichaelRoberts Feb 06 2009 at 04:49

जावास्क्रिप्ट हमेशा पास-पास-मूल्य है ; सब कुछ मूल्य प्रकार का है।

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

इस अवसर पर वे अपने बेस प्रोटोटाइप से विरासत में मिले कुछ सदस्य कार्यों और संपत्तियों का लाभ उठा सकते हैं, लेकिन यह केवल सुविधा के लिए है। इसका मतलब यह नहीं है कि वे स्वयं वस्तु हैं। संदर्भ के लिए निम्नलिखित प्रयास करें:

x = "test";
alert(x.foo);
x.foo = 12;
alert(x.foo);

दोनों अलर्ट में आपको अपरिभाषित मान मिलेगा।

13 zangw Dec 30 2015 at 09:20

जावास्क्रिप्ट में, मान का प्रकार पूरी तरह से नियंत्रित करता है कि क्या मान मूल्य-प्रति या संदर्भ-प्रतिलिपि द्वारा निर्दिष्ट किया जाएगा ।

आदिम मूल्य हमेशा मूल्य-कॉपी द्वारा असाइन / पास किए जाते हैं :

  • null
  • undefined
  • तार
  • संख्या
  • बूलियन
  • में प्रतीक ES6

यौगिक मूल्यों को हमेशा संदर्भ-प्रति द्वारा सौंपा / पास किया जाता है

  • वस्तुओं
  • सरणियों
  • समारोह

उदाहरण के लिए

var a = 2;
var b = a; // `b` is always a copy of the value in `a`
b++;
a; // 2
b; // 3

var c = [1,2,3];
var d = c; // `d` is a reference to the shared `[1,2,3]` value
d.push( 4 );
c; // [1,2,3,4]
d; // [1,2,3,4]

उपरोक्त स्निपेट में, क्योंकि 2एक स्केलर आदिम है, aउस मूल्य की एक प्रारंभिक प्रतिलिपि रखता है, और bउसे मूल्य की एक और प्रतिलिपि सौंपी जाती है। बदलते समय b, आप किसी भी तरह से मूल्य में बदलाव नहीं कर रहे हैं a

लेकिन दोनों cऔर dएक ही साझा मूल्य के लिए अलग-अलग संदर्भों हैं [1,2,3], जो एक यौगिक मूल्य है। यह ध्यान रखना महत्वपूर्ण है कि मूल्य का cन तो dअधिक और न ही "मालिक" है [1,2,3]- दोनों मूल्य के बराबर समकक्ष संदर्भ हैं। इसलिए, जब .push(4)वास्तविक साझा arrayमूल्य को संशोधित ( ) करने के लिए संदर्भ का उपयोग किया जाता है, तो यह सिर्फ एक साझा मूल्य को प्रभावित कर रहा है, और दोनों संदर्भ नए संशोधित मूल्य को संदर्भित करेंगे [1,2,3,4]

var a = [1,2,3];
var b = a;
a; // [1,2,3]
b; // [1,2,3]

// later
b = [4,5,6];
a; // [1,2,3]
b; // [4,5,6]

जब हम असाइनमेंट बनाते b = [4,5,6]हैं, तो हम प्रभावित करने के लिए बिल्कुल कुछ नहीं कर रहे हैं जहां aअभी भी संदर्भित है ( [1,2,3])। ऐसा करने के लिए, एक संदर्भ के बजाय bएक सूचक होना चाहिए - लेकिन जेएस में ऐसी कोई क्षमता मौजूद नहीं है!aarray

function foo(x) {
    x.push( 4 );
    x; // [1,2,3,4]

    // later
    x = [4,5,6];
    x.push( 7 );
    x; // [4,5,6,7]
}

var a = [1,2,3];

foo( a );

a; // [1,2,3,4]  not  [4,5,6,7]

जब हम तर्क में पास होते हैं a, तो यह aसंदर्भ की एक प्रति प्रदान करता है xxऔर aएक ही [1,2,3]मूल्य पर इंगित अलग संदर्भ हैं । अब, फ़ंक्शन के अंदर, हम उस संदर्भ का उपयोग स्वयं मान को बदलने के लिए कर सकते हैं ( push(4))। लेकिन जब हम असाइनमेंट बनाते हैं x = [4,5,6], तो यह किसी भी तरह से प्रभावित नहीं होता है जहां प्रारंभिक संदर्भ aइंगित कर रहा है - अभी भी (अब संशोधित) [1,2,3,4]मान पर इंगित करता है ।

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

foo( a.slice() );

यौगिक मूल्य (ऑब्जेक्ट, एरे, आदि) जो संदर्भ-कॉपी द्वारा पारित किया जा सकता है

function foo(wrapper) {
    wrapper.a = 42;
}

var obj = {
    a: 2
};

foo( obj );

obj.a; // 42

यहाँ, objअदिश आदिम संपत्ति के लिए एक आवरण के रूप में कार्य करता है a। जब पास किया जाता है foo(..), तो objसंदर्भ की एक कॉपी को wrapperपैरामीटर में सेट किया जाता है। अब हम wrapperसाझा किए गए ऑब्जेक्ट तक पहुंचने के लिए संदर्भ का उपयोग कर सकते हैं , और इसकी संपत्ति को अपडेट कर सकते हैं। फ़ंक्शन के पूरा होने के बाद, obj.aअद्यतन मूल्य देखेंगे 42

स्रोत

10 kianasirzadeh Nov 14 2019 at 07:48

खैर, यह 'प्रदर्शन' और 'गति' के बारे में है और एक प्रोग्रामिंग भाषा में सरल शब्द 'मेमोरी मैनेजमेंट' में।

जावास्क्रिप्ट में हम में दो परत मूल्यों रख सकते हैं: type1 - objectsऔर type2 जैसे मूल्य का निर्माण सभी अन्य प्रकार के stringऔर booleanऔर आदि

यदि आप स्मृति की कल्पना नीचे वर्गों के रूप में करते हैं जो उनमें से हर एक में सिर्फ एक टाइप 2-मूल्य को बचाया जा सकता है:

प्रत्येक टाइप 2 -मूल्य (हरा) एक एकल वर्ग है जबकि टाइप 1-मूल्य (नीला) उनमें से एक समूह है :

मुद्दा यह है कि यदि आप टाइप 2-मूल्य को इंगित करना चाहते हैं, तो पता स्पष्ट है, लेकिन यदि आप टाइप 1-मान के लिए एक ही काम करना चाहते हैं, जो आसान नहीं है! :

और अधिक जटिल कहानी में:

इसलिए यहाँ संदर्भ हमें बचा सकते हैं:

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

लेकिन हम बैंगनी तीर के साथ एक ही काम नहीं कर सकते हैं, हम 'जॉन' सेल को यहां या कई अन्य चीजों में स्थानांतरित करना चाह सकते हैं ..., इसलिए बैंगनी तीर अपनी जगह पर चिपक जाएगा और बस विशिष्ट तीर जो इसे सौंपा गया था, वह आगे बढ़ जाएगा ...

एक बहुत ही भ्रामक स्थिति यह है कि आप महसूस नहीं कर सकते कि आपके संदर्भित चर कैसे बदलते हैं, आइए एक बहुत अच्छे उदाहरण पर एक नज़र डालें:

let arr = [1, 2, 3, 4, 5]; //arr is an object now and a purple arrow is indicating it
let obj2 = arr; // now, obj2 is another purple arrow that is indicating the value of arr obj
let obj3 = ['a', 'b', 'c'];
obj2.push(6); // first pic below - making a new hand for the blue circle to point the 6
//obj2 = [1, 2, 3, 4, 5, 6]
//arr = [1, 2, 3, 4, 5, 6]
//we changed the blue circle object value (type1-value) and due to arr and obj2 are indicating that so both of them changed
obj2 = obj3; //next pic below - changing the direction of obj2 array from blue circle to orange circle so obj2 is no more [1,2,3,4,5,6] and it's no more about changing anything in it but we completely changed its direction and now obj2 is pointing to obj3
//obj2 = ['a', 'b', 'c'];
//obj3 = ['a', 'b', 'c'];

8 AshishSinghRawat Sep 26 2018 at 00:31

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

मान से गुजरें (आदिम प्रकार)

var a = 3;
var b = a;

console.log(a); // a = 3
console.log(b); // b = 3

a=4;
console.log(a); // a = 4
console.log(b); // b = 3
  • जावास्क्रिप्ट (स्ट्रिंग, संख्या, बूलियन, अपरिभाषित और अशक्त) में सभी आदिम प्रकार पर लागू होता है।
  • a को एक मेमोरी आवंटित की जाती है (0x001 कहते हैं) और b मेमोरी में मान की एक प्रति बनाता है (0x002 कहते हैं)।
  • इसलिए एक चर का मूल्य बदलना दूसरे को प्रभावित नहीं करता है, क्योंकि वे दोनों दो अलग-अलग स्थानों में रहते हैं।

संदर्भ (ऑब्जेक्ट्स) द्वारा पास करें

var c = { "name" : "john" };
var d = c;

console.log(c); // { "name" : "john" }
console.log(d); // { "name" : "john" }

c.name = "doe";

console.log(c); // { "name" : "doe" }
console.log(d); // { "name" : "doe" }
  • जावास्क्रिप्ट इंजन चर के लिए वस्तु प्रदान करता है c, और यह कुछ स्मृति को इंगित करता है, कहते हैं (0x012)।
  • जब d = c, इस चरण dमें समान स्थान (0x012) की ओर इशारा करता है।
  • दोनों चर के लिए किसी भी परिवर्तन मूल्य का मूल्य बदलना।
  • कार्य वस्तुएं हैं

विशेष मामला, संदर्भ (वस्तुओं) द्वारा पारित

c = {"name" : "jane"};
console.log(c); // { "name" : "jane" }
console.log(d); // { "name" : "doe" }
  • बराबर (=) ऑपरेटर नया मेमोरी स्पेस या पता सेट करता है
6 ZameerAnsari Aug 10 2017 at 19:43

जावास्क्रिप्ट में संदर्भों के बारे में मुझे जो पता है उसे साझा करना

जावास्क्रिप्ट में, जब किसी वस्तु को किसी चर के लिए निर्दिष्ट किया जाता है, तो चर को दिया गया मान वस्तु का संदर्भ होता है:

var a = {
  a: 1,
  b: 2,
  c: 3
};
var b = a;

// b.c is referencing to a.c value
console.log(b.c) // Output: 3
// Changing value of b.c
b.c = 4
// Also changes the value of a.c
console.log(a.c) // Output: 4

4 CPerkins Dec 24 2016 at 01:43

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

सबसे पहले, अमूर्तता के कई स्तर हैं जो हर किसी को समझ में नहीं आते हैं। 4 या 5 वीं पीढ़ी की भाषाओं पर सीख चुके नए प्रोग्रामर को असेंबली या सी प्रोग्रामर से जुड़ी अवधारणाओं के बारे में अपने मन को लपेटने में कठिनाई हो सकती है, जो पॉइंटर्स टू पॉइंटर्स टू पॉइंटर्स से चरणबद्ध नहीं होते हैं। पास-दर-संदर्भ का अर्थ केवल फ़ंक्शन पैरामीटर चर का उपयोग करके संदर्भित ऑब्जेक्ट को बदलने की क्षमता नहीं है।

चर : एक प्रतीक की संयुक्त अवधारणा जो स्मृति में किसी विशेष स्थान पर एक मूल्य का संदर्भ देती है। यह शब्द आमतौर पर विवरणों पर चर्चा करने के लिए अकेले उपयोग किए जाने के लिए बहुत अधिक भरा हुआ है।

प्रतीक : पाठ स्ट्रिंग का उपयोग चर (यानी चर के नाम) को संदर्भित करने के लिए किया जाता है।

मूल्य : विशेष रूप से बिट मेमोरी में संग्रहीत और चर के प्रतीक का उपयोग करके संदर्भित।

मेमोरी लोकेशन : जहां एक वैरिएबल की वैल्यू स्टोर होती है। (स्थान खुद को स्थान पर संग्रहीत मूल्य से अलग एक संख्या द्वारा दर्शाया जाता है।)

फ़ंक्शन पैरामीटर : फ़ंक्शन में पारित चर को संदर्भित करने के लिए उपयोग की जाने वाली फ़ंक्शन परिभाषा में घोषित चर।

फ़ंक्शन तर्क : फ़ंक्शन के बाहर चर जो कॉलर द्वारा फ़ंक्शन को पास किया जाता है।

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

आदिम चर : चर जिसका मूल्य वास्तविक मूल्य है। यहां तक ​​कि यह अवधारणा विभिन्न भाषाओं के ऑटो-बॉक्सिंग और ऑब्जेक्ट-जैसे संदर्भों से जटिल हो सकती है, लेकिन सामान्य विचार यह है कि चर का मान किसी अन्य मेमोरी स्थान के लिए सूचक के बजाय चर के प्रतीक द्वारा दर्शाया गया वास्तविक मूल्य है।

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

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

कॉल / पास-बाय-संदर्भ : फ़ंक्शन तर्क का मान संबंधित फ़ंक्शन पैरामीटर द्वारा सीधे अपडेट / किया जा सकता है। यदि यह मदद करता है, तो फ़ंक्शन पैरामीटर तर्क के लिए एक प्रभावी "उपनाम" बन जाता है - वे प्रभावी रूप से समान स्मृति स्थान पर समान मान का संदर्भ देते हैं। यदि फ़ंक्शन तर्क ऑब्जेक्ट चर है, तो ऑब्जेक्ट के डेटा को बदलने की क्षमता पास-दर-मूल्य मामले से अलग नहीं है क्योंकि फ़ंक्शन पैरामीटर अभी भी तर्क के समान ऑब्जेक्ट को इंगित करेगा। लेकिन ऑब्जेक्ट चर मामले में, यदि फ़ंक्शन पैरामीटर पूरी तरह से अलग ऑब्जेक्ट पर सेट है, तो तर्क भी अलग ऑब्जेक्ट को इंगित करेगा - पास-बाय-वैल्यू केस में ऐसा नहीं होता है।

जावास्क्रिप्ट संदर्भ से नहीं गुजरती है। यदि आप बारीकी से पढ़ते हैं, तो आप महसूस करेंगे कि सभी विपरीत राय पास-बाय-वैल्यू का गलत मतलब निकालते हैं और वे गलत तरीके से निष्कर्ष निकालते हैं कि फ़ंक्शन पैरामीटर के माध्यम से किसी ऑब्जेक्ट के डेटा को अपडेट करने की क्षमता "पास-बाय-वैल्यू" का पर्याय है।

ऑब्जेक्ट क्लोन / कॉपी : एक नई ऑब्जेक्ट बनाई जाती है और मूल ऑब्जेक्ट का डेटा कॉपी किया जाता है। यह एक गहरी प्रतिलिपि या उथली प्रतिलिपि हो सकती है, लेकिन मुद्दा यह है कि एक नई वस्तु बनाई गई है। किसी वस्तु की प्रतिलिपि बनाना पास-दर-मूल्य से एक अलग अवधारणा है। कुछ भाषाएं क्लास ऑब्जेक्ट और स्ट्रक्चर्स (या पसंद) के बीच अंतर करती हैं, और विभिन्न प्रकारों के चर को पार करने के लिए अलग व्यवहार हो सकता है। लेकिन ऑब्जेक्ट चर को पार करते समय जावास्क्रिप्ट स्वचालित रूप से ऐसा कुछ भी नहीं करता है। लेकिन स्वचालित ऑब्जेक्ट क्लोनिंग की अनुपस्थिति पास-दर-संदर्भ में अनुवाद नहीं करती है।

4 georgeawg Jul 25 2018 at 22:47

जावास्क्रिप्ट संदर्भ द्वारा मूल्य और वस्तु प्रकारों से आदिम प्रकार गुजरता है

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

  1. किसी वस्तु को पास करने से वस्तु की नकल नहीं होती है।
  2. किसी फ़ंक्शन को दी गई वस्तु में उसके सदस्यों को फ़ंक्शन द्वारा संशोधित किया जा सकता है।
  3. फ़ंक्शन के लिए दिया गया एक आदिम मान फ़ंक्शन द्वारा संशोधित नहीं किया जा सकता है। एक प्रति बनाई जाती है।

मेरी पुस्तक में जिसे संदर्भ से गुजरना कहा जाता है।

- ब्रायन बी - किन प्रोग्रामिंग भाषाओं को संदर्भ द्वारा पारित किया जाता है?


अपडेट करें

यहाँ इसका खंडन किया गया है:

जावास्क्रिप्ट में कोई "पास बाय रेफरेंस" उपलब्ध नहीं है।

3 dpp Sep 16 2014 at 16:19

इसे समझने का मेरा सरल तरीका ...

  • किसी फ़ंक्शन को कॉल करते समय, आप तर्क चर की सामग्री (संदर्भ या मूल्य) पास कर रहे हैं, स्वयं चर नहीं।

    var var1 = 13;
    var var2 = { prop: 2 };
    
    //13 and var2's content (reference) are being passed here
    foo(var1, var2); 
    
  • फ़ंक्शन के अंदर, पैरामीटर चर, inVar1और inVar2, पास होने वाली सामग्री प्राप्त करें।

    function foo(inVar1, inVar2){
        //changing contents of inVar1 and inVar2 won't affect variables outside
        inVar1 = 20;
        inVar2 = { prop: 7 };
    }
    
  • चूंकि inVar2संदर्भ प्राप्त हुआ है { prop: 2 }, आप ऑब्जेक्ट की संपत्ति के मूल्य को बदल सकते हैं।

    function foo(inVar1, inVar2){
        inVar2.prop = 7; 
    }
    
3 JohnSonderson Nov 01 2014 at 19:43

जावास्क्रिप्ट में एक फ़ंक्शन के लिए तर्क पास करना सी में पॉइंटर मान द्वारा पासिंग पैरामीटर के अनुरूप है:

/*
The following C program demonstrates how arguments
to JavaScript functions are passed in a way analogous
to pass-by-pointer-value in C. The original JavaScript
test case by @Shog9 follows with the translation of
the code into C. This should make things clear to
those transitioning from C to JavaScript.

function changeStuff(num, obj1, obj2)
{
    num = num * 10;
    obj1.item = "changed";
    obj2 = {item: "changed"};
}

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};
changeStuff(num, obj1, obj2);
console.log(num);
console.log(obj1.item);    
console.log(obj2.item);

This produces the output:

10
changed
unchanged
*/

#include <stdio.h>
#include <stdlib.h>

struct obj {
    char *item;
};

void changeStuff(int *num, struct obj *obj1, struct obj *obj2)
{
    // make pointer point to a new memory location
    // holding the new integer value
    int *old_num = num;
    num = malloc(sizeof(int));
    *num = *old_num * 10;
    // make property of structure pointed to by pointer
    // point to the new value
    obj1->item = "changed";
    // make pointer point to a new memory location
    // holding the new structure value
    obj2 = malloc(sizeof(struct obj));
    obj2->item = "changed";
    free(num); // end of scope
    free(obj2); // end of scope
}

int num = 10;
struct obj obj1 = { "unchanged" };
struct obj obj2 = { "unchanged" };

int main()
{
    // pass pointers by value: the pointers
    // will be copied into the argument list
    // of the called function and the copied
    // pointers will point to the same values
    // as the original pointers
    changeStuff(&num, &obj1, &obj2);
    printf("%d\n", num);
    puts(obj1.item);
    puts(obj2.item);
    return 0;
}
3 DannyNiu Jul 28 2017 at 20:17

प्रोग्रामिंग भाषा वकीलों के लिए, मैं ECMAScript 5.1 (जो कि नवीनतम संस्करण की तुलना में पढ़ना आसान है) के निम्नलिखित अनुभागों से गुजरा है, और जहाँ तक हो सकता है, यह ECMAScript मेलिंग सूची से पूछें ।

टीएल; डीआर : एवरीथिंगगेज वैल्यू द्वारा पारित किया गया है, लेकिन ऑब्जेक्ट्स के गुण संदर्भ हैं, और ऑब्जेक्ट की परिभाषा मानक में कमी है।

तर्क सूचियों का निर्माण

धारा 11.2.4 "तर्क सूचियाँ" केवल 1 तर्क से मिलकर एक तर्क सूची तैयार करने पर निम्नलिखित कहती है:

उत्पादन तर्कवादी: निरूपण। मूल्यांकन का मूल्यांकन इस प्रकार किया जाता है:

  1. मान लें कि असाइनमेंट का मूल्यांकन करने का परिणाम है।
  2. आज्ञा देना हो GetValue (रेफरी)।
  3. ऐसी सूची लौटाएं जिसका एकमात्र आइटम arg हो।

अनुभाग उन मामलों की भी गणना करता है जहां तर्क सूची में 0 या> 1 तर्क हैं।

इस प्रकार, सब कुछ संदर्भ द्वारा पारित किया जाता है।

वस्तु गुणों की पहुँच

धारा 11.2.1 "संपत्ति अभिदाता"

प्रोडक्शन मेम्बर एक्सप्रेशन: मेंबर एक्सप्रेशन [एक्सप्रेशन] का मूल्यांकन निम्नानुसार किया जाता है:

  1. बता दें कि BaseReference सदस्य एक्सप्रेशन का मूल्यांकन करने का परिणाम है।
  2. BaseValue GetValue (BaseReference) होने दें।
  3. बता दें कि प्रॉपर्टीनामेप्रेशन एक्सप्रेशन के मूल्यांकन का परिणाम है।
  4. चलिए PropertyNameValue GetValue (propertyNameReference) बनें।
  5. CheckObjectCoercible (baseValue) को कॉल करें।
  6. चलिए PropertyNameString ToString (संपत्तिNameValue) है।
  7. अगर वाक्य रचना का मूल्यांकन किया जा रहा है जो सख्त मोड कोड में समाहित है, तो इसे सख्त होने दें, अन्यथा कड़ाई को गलत होने दें।
  8. मान के प्रकार को लौटाएं जिसका आधार मान baseValue है और जिसका संदर्भित नाम गुणनाम है, और जिसका सख्त मोड ध्वज सख्त है।

इस प्रकार, वस्तुओं के गुण हमेशा संदर्भ के रूप में उपलब्ध होते हैं।

संदर्भ पर

यह खंड 8.7 में वर्णित है "संदर्भ विनिर्देश प्रकार", कि संदर्भ भाषा में वास्तविक प्रकार नहीं हैं - वे केवल डिलीट, टाइपोफ़ और असाइनमेंट ऑपरेटरों के व्यवहार का वर्णन करने के लिए उपयोग किए जाते हैं।

"ऑब्जेक्ट" की परिभाषा

इसे 5.1 संस्करण में परिभाषित किया गया है कि "एक वस्तु गुणों का संग्रह है"। इसलिए, हम अनुमान लगा सकते हैं, कि वस्तु का मूल्य संग्रह है, लेकिन संग्रह का मूल्य क्या है यह कल्पना में खराब रूप से परिभाषित किया गया है, और समझने के लिए थोड़े प्रयास की आवश्यकता है ।

3 miguelr Apr 20 2019 at 13:06

MDN डॉक्स इसे स्पष्ट रूप से समझाता है, वह भी बिना क्रिया के:

फ़ंक्शन कॉल के पैरामीटर फ़ंक्शन के तर्क हैंमूल्य द्वारा कार्यों को तर्क पारित किए जाते हैं । यदि फ़ंक्शन किसी तर्क के मान को बदलता है, तो यह परिवर्तन विश्व स्तर पर या कॉलिंग फ़ंक्शन में परिलक्षित नहीं होता है। हालाँकि, ऑब्जेक्ट संदर्भ मान हैं, भी, और वे विशेष हैं: यदि फ़ंक्शन संदर्भित ऑब्जेक्ट के गुणों को बदलता है, तो यह फ़ंक्शन फ़ंक्शन के बाहर दिखाई देता है, (...)

स्रोत: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Description

2 JonasWilms Jul 26 2020 at 22:32

अवलोकन: यदि इंजन की अंतर्निहित स्मृति की जांच करने के लिए पर्यवेक्षक के लिए कोई रास्ता नहीं है, तो यह निर्धारित करने का कोई तरीका नहीं है कि एक अपरिवर्तनीय मूल्य की नकल की जाती है या एक संदर्भ पास हो जाता है।

अंतर्निहित मेमोरी मॉडल में जावास्क्रिप्ट कमोबेश अज्ञेयवादी है। संदर्भ as जैसी कोई चीज नहीं है । जावास्क्रिप्ट में मान हैं । दो चर एक ही मूल्य (या अधिक सटीक: दो पर्यावरण रिकॉर्ड एक ही मूल्य बांध सकते हैं ) धारण कर सकते हैं । एकमात्र प्रकार के मान जिन्हें उत्परिवर्तित किया जा सकता है, वे हैं उनके सार [[प्राप्त करें]] और [[सेट]] संचालन के माध्यम से ऑब्जेक्ट। यदि आप कंप्यूटर और मेमोरी के बारे में भूल जाते हैं, तो आपको जावा स्क्रिप्ट व्यवहार का वर्णन करने की आवश्यकता है, और यह आपको विनिर्देश को समझने की अनुमति देता है।

 let a = { prop: 1 };
 let b = a; // a and b hold the same value
 a.prop = "test"; // the object gets mutated, can be observed through both a and b
 b = { prop: 2 }; // b holds now a different value
 

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

तो वास्तव में आप कह सकते हैं कि जावास्क्रिप्ट "पास वैल्यू" है, जबकि मूल्य साझा किया जा सकता है, आप कह सकते हैं कि जावास्क्रिप्ट "संदर्भ द्वारा पास" है, जो निम्न स्तर की भाषाओं के प्रोग्रामर के लिए एक उपयोगी तार्किक अमूर्त हो सकता है, या आप व्यवहार को "कॉल बाय शेयरिंग" कह सकते हैं। जैसा कि जावास्क्रिप्ट में एक संदर्भ के रूप में ऐसी कोई बात नहीं है, ये सभी न तो गलत हैं और न ही बिंदु पर हैं। इसलिए मुझे नहीं लगता कि इसका उत्तर खोजना विशेष रूप से उपयोगी है।

Specification विनिर्देश में संदर्भ शब्द पारंपरिक अर्थों में एक संदर्भ नहीं है। यह एक वस्तु और एक संपत्ति के नाम के लिए एक कंटेनर है, और एक मध्यवर्ती मूल्य है (उदाहरण के लिए a.bमूल्यांकन करता है Reference { value = a, name = "b" })। शब्द का संदर्भ कभी-कभी विशिष्ट खंडों में विनिर्देश में भी दिखाई देता है।

1 lid May 17 2014 at 08:01

सबसे अधिक स्पष्ट व्याख्या मुझे AirBNB स्टाइल गाइड में मिली थी :

  • प्राइमिटिव्स : जब आप एक आदिम प्रकार का उपयोग करते हैं तो आप सीधे उसके मूल्य पर काम करते हैं

    • तार
    • संख्या
    • बूलियन
    • शून्य
    • अपरिभाषित

जैसे:

var foo = 1,
    bar = foo;

bar = 9;

console.log(foo, bar); // => 1, 9
  • जटिल : जब आप एक जटिल प्रकार का उपयोग करते हैं तो आप इसके मूल्य के संदर्भ में काम करते हैं

    • वस्तु
    • सरणी
    • समारोह

जैसे:

var foo = [1, 2],
    bar = foo;

bar[0] = 9;

console.log(foo[0], bar[0]); // => 9, 9

यानी प्रभावी रूप से आदिम प्रकार मूल्य द्वारा पारित किए जाते हैं, और जटिल प्रकार संदर्भ द्वारा पारित किए जाते हैं।

1 steviejay Oct 29 2016 at 21:50

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

साझा करने से कॉल के शब्दार्थक उस संदर्भ के कॉल असाइनमेंट से भिन्न होते हैं, जो फ़ंक्शन के भीतर कार्य तर्कों के लिए कॉल करने वाले (संदर्भ शब्दार्थ द्वारा विपरीत) के लिए दृश्यमान नहीं होते हैं [उद्धरण वांछित], इसलिए यदि कोई चर पारित किया गया था, तो यह संभव नहीं है कॉलर के दायरे में उस चर पर असाइनमेंट का अनुकरण करने के लिए। हालाँकि, फ़ंक्शन के पास उसी ऑब्जेक्ट तक पहुंच है, जैसे कि कॉलर (कोई प्रतिलिपि नहीं बनाई गई है), उन ऑब्जेक्ट्स के लिए म्यूटेशन, यदि ऑब्जेक्ट्स उत्परिवर्तित होते हैं, तो फ़ंक्शन के भीतर कॉल करने वाले को दिखाई देते हैं, जो कि मूल्य से कॉल से भिन्न हो सकता है। शब्दार्थ। फ़ंक्शन के भीतर एक उत्परिवर्तनीय वस्तु के म्यूटेशन कॉलर को दिखाई देते हैं क्योंकि ऑब्जेक्ट को कॉपी या क्लोन नहीं किया जाता है - इसे साझा किया जाता है।

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

1 Narayon Oct 19 2016 at 19:07

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

int myAge = 14;
increaseAgeByRef(myAge);
function increaseAgeByRef(int &age) {
  *age = *age + 1;
}

&ageलिए एक संदर्भ है myAge, लेकिन अगर आप मूल्य चाहते हैं आप, संदर्भ कन्वर्ट करने के लिए उपयोग कर रहा है *age

जावास्क्रिप्ट एक उच्च स्तरीय भाषा है जो आपके लिए यह रूपांतरण करती है।

इसलिए, हालांकि ऑब्जेक्ट्स संदर्भ द्वारा पारित किए जाते हैं, भाषा संदर्भ पैरामीटर को मान में परिवर्तित करती है। आपको &फ़ंक्शन परिभाषा पर, संदर्भ द्वारा इसे पास करने की आवश्यकता नहीं है , न ही *, फ़ंक्शन बॉडी पर, मान को संदर्भ में परिवर्तित करने के लिए, जावास्क्रिप्ट आपके लिए करता है।

इसीलिए जब आप किसी फ़ंक्शन के अंदर किसी ऑब्जेक्ट को बदलने का प्रयास करते हैं, तो उसका मान (यानी age = {value:5}) बदलकर, परिवर्तन जारी नहीं रहता है, लेकिन यदि आप इसे बदलते हैं तो यह गुण (यानी age.value = 5) है।

और अधिक जानें