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




pass-by-reference pass-by-value (20)

sharing what I know of references in javascript

In Javascript, objects are stored as references:

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

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

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


  1. Primitives (Number, Boolean) are passed by value.
    • Strings are immutable, so it doesn't really matter for them.
  2. Objects are passed by reference ( the reference is passed by value)

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

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

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 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}

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


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

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

  • 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 एक स्केलर आदिम है, इसमें उस मान की एक प्रारंभिक प्रति है, और b को मूल्य की एक और प्रतिलिपि सौंपी जाती है। b बदलते समय, आप किसी भी तरह से मूल्य को बदल नहीं रहे हैं।

लेकिन 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] करते हैं, तो हम अभी भी संदर्भित करने के लिए बिल्कुल कुछ भी नहीं कर रहे हैं (अभी भी [1,2,3] )। ऐसा करने के लिए, b को array संदर्भ के बजाय एक सूचक होना होगा - लेकिन जेएस में ऐसी कोई क्षमता मौजूद नहीं है!

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]

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

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

foo( a.slice() );

कंपाउंड मान (ऑब्जेक्ट, सरणी, आदि) जिसे संदर्भ-प्रति द्वारा पारित किया जा सकता है

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

var obj = {
    a: 2
};

foo( obj );

obj.a; // 42

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

Source


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

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

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


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

  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

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

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

एक बात जो मैं अभी भी समझ नहीं पा रहा हूं। नीचे कोड जांचें। कोई विचार?

function A() {}
A.prototype.foo = function() {
    return 'initial value';
}


function B() {}
B.prototype.bar = A.prototype.foo;

console.log(A.prototype.foo()); //initial value
console.log(B.prototype.bar()); //initial value

A.prototype.foo = function() {
    return 'changed now';
}

console.log(A.prototype.foo()); //changed now
console.log(B.prototype.bar()); //Why still 'initial value'???

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

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.item को बदलने से कार्य के बाहर obj1 पर कोई प्रभाव नहीं पड़ेगा। यदि यह संदर्भ द्वारा शुद्ध पास था, तो सब कुछ बदल गया होगा। num 100 होगी, और obj2.item "changed" पढ़ेगा।

इसके बजाए, स्थिति यह है कि पास की गई वस्तु मूल्य से गुजरती है। लेकिन मूल्य से गुजरने वाली वस्तु स्वयं ही एक संदर्भ है। तकनीकी रूप से, इसे call-by-sharing कहा जाता है।

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


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

उदाहरण:

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

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

var x = {member:"foo"};

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

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

आउटपुट:

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

before changeMember: foo
in changeMember: bar
after changeMember: bar

An easy way to determine whether something is "pass by reference" is whether you can write a "swap" function. For example, in C, you can do:

void swap(int *i, int *j)
{
    int t;
    t = *i;
    *i = *j;
    *j = t;
}

If you can't do the equivalent of that in Javascript, it is not "pass by reference".


For programming language lawyers, I've went through the following sections of ECMAScript 5.1 (which is easier to read than the latest edition), and go as far as asking it on the ECMAScript mailing list.

TL;DR : Everythings're passed by value, but properties of Objects are references, and the definition of Object is creepily lacking in the standard.

Construction of Argument Lists

Section 11.2.4 "Argument Lists" says the following on producing a argument list consisting of only 1 argument:

The production ArgumentList : AssignmentExpression is evaluated as follows:

  1. Let ref be the result of evaluating AssignmentExpression.
  2. Let arg be GetValue(ref).
  3. Return a List whose sole item is arg.

The section also enumerate cases where argument list has 0 or >1 arguments.

Thus, everything's are passed by reference.

Access of Object Properties

Section 11.2.1 "Property Accessors"

The production MemberExpression : MemberExpression [ Expression ] is evaluated as follows:

  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be GetValue(baseReference).
  3. Let propertyNameReference be the result of evaluating Expression.
  4. Let propertyNameValue be GetValue(propertyNameReference).
  5. Call CheckObjectCoercible(baseValue).
  6. Let propertyNameString be ToString(propertyNameValue).
  7. If the syntactic production that is being evaluated is contained in strict mode code, let strict be true, else let strict be false.
  8. Return a value of type Reference whose base value is baseValue and whose referenced name is propertyNameString, and whose strict mode flag is strict.

Thus, properties of Objects are always available as reference.

On Reference

It is described in section 8.7 "The Reference Specification Type", that references are not real types in the language - they're only used to describe the behavior of the delete, the typeof, and the assignment operators.

Definition of "Object"

It is defined in 5.1 edition that "An Object is a collection of properties". Therefore, we can infer, that the value of the object is the collection, but as to what is the value of the collection is poorly defined in the spec, and requires a bit of effort to understand.


I would say it is pass-by-copy -

Consider arguments and variable objects are objects created during the execution context created in the beginning of function invocation - and your actual value/reference passed into the function just get stored in this arguments + variable objects.

Simply speaking, for primitive types, the values get copied in the beginning of function call, for object type, the reference get copied.


I've read through these answers multiple times, but didn't REALLY get it until I learned about the technical definition of "Call by sharing" as termed by Barbara Liskov

The semantics of call by sharing differ from call by reference in that assignments to function arguments within the function aren't visible to the caller (unlike by reference semantics)[citation needed], so eg if a variable was passed, it is not possible to simulate an assignment on that variable in the caller's scope. However, since the function has access to the same object as the caller (no copy is made), mutations to those objects, if the objects are mutable, within the function are visible to the caller, which may appear to differ from call by value semantics. Mutations of a mutable object within the function are visible to the caller because the object is not copied or cloned — it is shared.

That is, parameter references are alterable if you go and access the parameter value itself. On the other hand, assignment to a parameter will disappear after evaluation, and is non-accessible to the function caller.


In some case, this may be helpful to alter anArg :

function alterMyArg(func) {
    // process some data
    // ...
    func(data);
}

alertMyArg(function(d) {anArg = d;});

My simple way to understand this...

  • When calling a function, you are passing the content (reference or value) of the argument variables, not the the variables themselves.

    var var1 = 13;
    var var2 = { prop: 2 };
    
    //13 and var2's content (reference) are being passed here
    foo(var1, var2); 
    
  • Inside the function, parameter variables, inVar1 and inVar2 , receive the contents being passed.

    function foo(inVar1, inVar2){
        //changing contents of inVar1 and inVar2 won't affect variables outside
        inVar1 = 20;
        inVar2 = { prop: 7 };
    }
    
  • Since inVar2 received the reference of { prop: 2 } , you can change the value of the object's property.

    function foo(inVar1, inVar2){
        inVar2.prop = 7; 
    }
    

Primitives are passed by value and objects are passed by reference. This is quite different from other languages like C, VB or Delphi. I can't say how they handle objects and primitives exactly, but I know of VB and Delphi that it can (and should) be specified.

php does something similar since version 5: all objects are passed by reference, but all primitives may be passed by reference, if preceeded by an ampersand (&). Otherwise primitives are passed by value.

So in javascript, if I pass an object X into a function via a parameter, it will still be X. If you are changing data inside the function (or any other object, but that's not important) that new value is also available outside the function.


Semantics!! Setting concrete definitions will necessarily make some answers and comments incompatible since they are not describing the same thing even when using the same words and phrases, but it is critical to get past the confusion (especially for new programmers).

First of all, there are multiple levels of abstraction that not everyone seems to grasp. Newer programmers who have learned on 4th or 5th generation languages may have difficulty wrapping their mind around concepts familiar to assembly or C programmers not phased by pointers to pointers to pointers. Pass-by-reference does not simply mean the ability to change a referenced object using a function parameter variable.

Variable : Combined concept of a symbol which references a value at a particular location in memory. This term is usually too loaded to be used alone in discussing details.

Symbol : Text string used to refer to variable (ie variable's name).

Value : Particular bits stored in memory and referenced using variable's symbol.

Memory location : Where a variable's value is stored. (The location itself is represented by a number separate from the value stored at the location.)

Function parameter : Variable declared in a function definition, used for referencing variables passed to the function.

Function argument : Variable outside the function which is passed to the function by the caller.

Object variable : Variable whose basic underlying value is not the "object" itself, rather its value is a pointer (memory location value) to another location in memory where the object's actual data is stored. In most higher-generation languages, the "pointer" aspect is effectively hidden by automatic de-referencing in various contexts.

Primitive variable : Variable whose value IS the actual value. Even this concept can be complicated by auto-boxing and object-like contexts of various languages, but the general ideas is that the variable's value IS the actual value represented by the variable's symbol rather than a pointer to another memory location.

Function arguments and parameters are not the same thing. Also, a variable's value is not the variable's object (as already pointed out by various people, but apparently ignored). These distinctions are critical to proper understanding.

Pass-by-value or Call-by-sharing (for objects) : The function argument's value is COPIED to another memory location which is referenced by the function's parameter symbol (regardless of whether it's on the stack or heap). In other words, the function parameter received a copy of the passed argument's value... AND (critical) the argument's value IS NEVER UPDATED / ALTERED / CHANGED by the calling function. Remember, an object variable's value is NOT the object itself, rather it is the pointer to the object, so passing an object variable by value copies the pointer to the function parameter variable. The function parameter's value points to the exact same object in memory. The object data itself can be altered directly via the function parameter, BUT the function argument's value IS NEVER UPDATED, so it will continue to point to the same object throughout and even after the function call (even if its object's data was altered or if the function parameter is assigned a different object altogether). It is incorrect to conclude that the function argument was passed by reference just because the referenced object is updatable via the function parameter variable.

Call / Pass-by-reference : The function argument's value can/will be updated directly by the corresponding function parameter. If it helps, the function parameter becomes an effective "alias" for the argument--they effectively refer to the same value at the same memory location. If a function argument is an object variable, the ability to change the object's data is no different than the pass-by-value case since the function parameter will still point to the same object as the argument. But in the object variable case, if the function parameter is set to a completely different object, then the argument will likewise also point to the different object--this does not happen in the pass-by-value case.

JavaScript does not pass by reference. If you read closely, you will realize that all contrary opinions misunderstand what is meant by pass-by-value and they falsely conclude that the ability to update an object's data via the function parameter is synonymous to "pass-by-value".

Object clone/copy : A new object is created and the original object's data is copied. This can be a deep copy or shallow copy, but the point is that a new object is created. Creating a copy of an object is a separate concept from pass-by-value. Some languages distinguish between class object and structs (or the like), and may have different behavior for passing variables of the different types. But JavaScript does not do anything like this automatically when passing object variables. But the absence of automatic object cloning does not translate to pass-by-reference.


The most succinct explanation I found was in the AirBNB style guide :

  • Primitives : When you access a primitive type you work directly on its value

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

उदाहरण के लिए:

var foo = 1,
    bar = foo;

bar = 9;

console.log(foo, bar); // => 1, 9
  • Complex : When you access a complex type you work on a reference to its value

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

उदाहरण के लिए:

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

bar[0] = 9;

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

Ie effectively primitive types are passed by value, and complex types are passed by reference.


  • When an object is created, it exists on the heap.
  • When a primitive value is established, it lives on the stack.
  • In order to use either, you must have a variable associated with it.

With an object, the variable is essentially a pointer on the stack that points to the memory location on the heap where the object is stored. With a primitive, the variable and the value are stored together on the stack.

When you pass an object variable in JavaScript, it is always passed by Reference, meaning that the a copy of the REFERENCE is passed to the callee. If the underlying object is manipulated by the callee, the original object will be modified outside the function as well.

जब आप जावास्क्रिप्ट में एक स्टैक वैरिएबल पास करते हैं, तो वास्तविक मान की एक प्रति कैली को पास की जाती है। यदि कैली प्राप्त मान को संशोधित करता है, तो फ़ंक्शन के बाहर मान संशोधित नहीं किया जाता है।






pass-by-value