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




pass-by-reference pass-by-value (25)

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

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


Answers

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

उदाहरण:

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

I have found the extend method of the Underscore.js library very useful when I want to pass in an object as a parameter which may either be modified or replaced entirely.

function replaceOrModify(aObj) {
  if (modify) {

    aObj.setNewValue('foo');

  } else {

   var newObj = new MyObject();
   // _.extend(destination, *sources) 
   _.extend(newObj, aObj);
  }
}

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

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


  • 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.

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


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

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

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}

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. primitive type variable like string,number are always pass as pass by value.
  2. Array and Object is passed as pass by reference or pass by value based on these two condition.

    • if you are changing value of that Object or array with new Object or Array then it is pass by Value.

      object1 = {item: "car"}; array1=[1,2,3];

    here you are assigning new object or array to old one.you are not changing the value of property of old object.so it is pass by value.

    • if you are changing a property value of an object or array then it is pass by Reference.

      object1.key1= "car"; array1[0]=9;

    here you are changing a property value of old object.you are not assigning new object or array to old one.so it is pass by reference.

कोड

    function passVar(object1, object2, number1) {

        object1.key1= "laptop";
        object2 = {
            key2: "computer"
        };
        number1 = number1 + 1;
    }

    var object1 = {
        key1: "car"
    };
    var object2 = {
        key2: "bike"
    };
    var number1 = 10;

    passVar(object1, object2, number1);
    console.log(object1.key1);
    console.log(object2.key2);
    console.log(number1);

Output: -
    laptop
    bike
    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


जेएस में "संदर्भ द्वारा पास" शब्द के उपयोग के बारे में कुछ चर्चा here , लेकिन आपके प्रश्न का उत्तर देने के लिए:

एक ऑब्जेक्ट स्वचालित रूप से संदर्भित करने की आवश्यकता के बिना, संदर्भ द्वारा स्वचालित रूप से पारित किया जाता है

(ऊपर वर्णित लेख से।)


Passing arguments to a function in JavaScript is analogous to passing parameters by pointer value in C:

/*
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;
}

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".


All function arguments in ECMAScript are passed by value. This means that the value outside of the function is copied into an argument on the inside of the function the same way a value is copied from one variable to another. If the value is primitive, then it acts just like a primitive variable copy, and if the value is a reference, it acts just like a reference variable copy. This is often a point of confusion for developers, because variables are accessed both by value and by reference, but arguments are passed only by value. When an argument is passed by value, the value is copied into a local variable (a named argument and, in ECMAScript, a slot in the arguments object). When an argument is passed by reference, the location of the value in memory is stored into a local variable, which means that changes to the local variable are refl ected outside of the function. (This is not possible in ECMAScript.)


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

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

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


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

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.


  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)

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.


Simple values inside functions will not change those values outside of the function (they are passed by value), whereas complex ones will (they are passed by reference).

function willNotChange(x) {

x = 1;

}

var x = 1000;

willNotChange(x);

document.write('After function call, x = ' + x + '<br>'); //still 1000

function willChange(y) {

y.num = 2;

}

var y = {num: 2000}; 

willChange(y);
document.write('After function call y.num = ' + y.num + '<br>'); //now 2, not 2000

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.


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

  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

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.


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

मूल्य / संदर्भ से गुज़रने के बारे में जो कुछ भी आप जानते हैं उसे फेंकने का समय है।

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

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

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 नहीं बदल सका ... क्यों ?? क्योंकि तार अपरिवर्तनीय हैं और हमने इसे म्यूट नहीं किया। हमने जो कुछ किया वह "आरई असाइन" पसंदीदा स्ट्रिंग को एक नई स्ट्रिंग पर था। यह अनिवार्य रूप से स्ट्रिंग 1 से डिस्कनेक्ट हो गया। पिछले उदाहरण में, जब हमने अपना ऑब्जेक्ट बदल दिया, हमने कुछ भी असाइन नहीं किया था। (ठीक है, असल में ... हमने किया, हमने नाम की संपत्ति को एक नई स्ट्रिंग में सौंपा।) इसके बजाय, हमने उस ऑब्जेक्ट को बस म्यूट कर दिया जो कनेक्शन को 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
otherObj = {
    firstName: 'Jack',
    lastName: 'Frost'
};

// Now, otherObj and myObject are assigned to 2 very different objects
// And mutating one object no longer mutates 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 no longer mutates 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'

In a low level language, if you want to pass a variable by reference you have to use a specific syntax in the creation of the function:

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

The &age is a reference to myAge , but if you want the value you have to convert the reference, using *age .

Javascript is a high level language that does this conversion for you. So, although objects are passed by reference, the language converts the reference parameter to the value. You don't need to use & , on the function definition, to pass it by reference, neither * , on the function body, to convert the reference to the value, JS does it for you.

That's why when you try to change an object inside a function, by replacing it's value (ie age = {value:5} ), the change doesn't persist, but if you change it's properties (ie age.value = 5 ), it does.

और अधिक जानें


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

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

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

जावास्क्रिप्ट चलाने के एकमात्र उद्देश्य के लिए लिंक का उपयोग न करें।

Href = "#" का उपयोग पृष्ठ को शीर्ष पर स्क्रॉल करता है; शून्य (0) का उपयोग ब्राउज़र के भीतर नेविगेशन समस्याओं को बनाता है।

इसके बजाय, किसी लिंक के अलावा किसी तत्व का उपयोग करें:

<span onclick="myJsFunc()" class="funcActuator">myJsFunc</span>

और इसे सीएसएस के साथ स्टाइल करें:

.funcActuator { 
  cursor: default;
}

.funcActuator:hover { 
  color: #900;
}




javascript pass-by-reference pass-by-value