Javascript - primitive and reference types

In the code below, we are passing an object. So, according to javascript, we pass the link and manipulate.

var a = new Number(10); x(a); alert(a); function x(n) { n = n + 2; } 

But 10 are warned instead of 12. Why?

+7
javascript pass-by-reference
source share
6 answers

n is local to x , and first it is set to the same link as global a . The right-hand side of n + 2 then evaluated as a number (primitive). The left side of the assignment , n never evaluated, it is only an identifier . Therefore, our local variable is now set to the primitive value of the right side. The value referenced by a never changes. Cm

 var a = new Number(10); x(a); alert(a); // 10 function x(n) { alert(typeof n); // object n = n + 2; alert(typeof n); // number } 
+10
source share

When you calculate

 n + 2 

this results in a new "native number", even if n indeed an instance of the Number object.

Assigning n then simply changes the binding of the local variable n and does not change the instance of the Number object. You can see that with

 n = new Number(10); console.log(typeof n); // ---> "object" console.log(n + 2); // ---> 12 console.log(typeof (n+2)); // ---> "number" n = n + 2; console.log(typeof n); // ---> "number" 

There is no way in Javascript (either Python or Lisp) to pass the "address" of a variable so that the called function mutates it. The only thing you can do is pass the setter function ... for example:

 function foo(setter) { setter(42); } funciton bar() { var x = 12; foo(function(newx){x = newx;}); console.log(x); // ---> 42 } 
+4
source share

Let me try to answer it with examples:

 function modify(obj) { // modifying the object itself // though the object was passed as reference // it behaves as pass by value obj = {c:3}; } var a = {b:2} modify(a); console.log(a) // Object {b: 2} function increment(obj) { // modifying the value of an attribute // working on the same reference obj.b = obj.b + 1; } var a = {b:2} increment(a); console.log(a) // Object {b: 3} function augument(obj) { // augument an attribute // working on the same reference obj.c = 3; } var a = {b:2} augument(a); console.log(a) // Object {b: 2, c: 3} 

Please refer to JSFiddle for a working demo.

+2
source share

The answer is quite simple: since ECMAScript is passed by value, not by reference, and your code proves this. (More precisely, this is a send-exchange, which is a certain type of transmission by value.)

See Is JavaScript the default password or language? for more information.

ECMAScript uses pass-by-value, or rather, a special case of pass-by-value, where the passed value is always a pointer. This special case is also sometimes called call sharing, call sharing or shame.

This is the same convention used by Java (for objects), C # (default for reference types), Smalltalk, Python, Ruby, and more or less every object-oriented language ever created.

Note: some types (for example) of Number actually passed directly by value, rather than using a proxy pointer. However, since they are immutable, in this case, there is no observed behavioral difference between passing by value and sharing a call to an object, so you can greatly simplify your mental model by simply considering everything as a call to an object - an exchange. Just interpret these special cases as internal compiler optimizations that you don't need to worry about.

Here is a simple example that you can follow to define an agreement to send arguments to ECMAScript (or any other language after translating it):

 function isEcmascriptPassByValue(foo) { foo.push('More precisely, it is call-by-object-sharing!'); foo = 'No, ECMAScript is pass-by-reference.'; return; } var bar = ['Yes, of course, ECMAScript *is* pass-by-value!']; isEcmascriptPassByValue(bar); console.log(bar); // Yes, of course, ECMAScript *is* pass-by-value!, // More precisely, it is call-by-object-sharing! 

If you are familiar with C #, this is a very good way to understand the differences between passing by value and passing by reference for value types and reference types, since C # supports all 4 combinations: pass-by- value for value types ("traditional pass- by-value "), a rolling value for reference types (call sharing, call-by-object, call sharing differently, as in ECMAScript), pass-by reference for reference types and by-reference for value types.

(In fact, even if you do not know C #, this is not too difficult to do.)

 struct MutableCell { public string value; } class Program { static void IsCSharpPassByValue(string[] foo, MutableCell bar, ref string baz, ref MutableCell qux) { foo[0] = "More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value."; foo = new string[] { "C# is not pass-by-reference." }; bar.value = "For value types, it is *not* call-by-sharing."; bar = new MutableCell { value = "And also not pass-by-reference." }; baz = "It also supports pass-by-reference if explicitly requested."; qux = new MutableCell { value = "Pass-by-reference is supported for value types as well." }; } static void Main(string[] args) { var quux = new string[] { "Yes, of course, C# *is* pass-by-value!" }; var corge = new MutableCell { value = "For value types it is pure pass-by-value." }; var grault = "This string will vanish because of pass-by-reference."; var garply = new MutableCell { value = "This string will vanish because of pass-by-reference." }; IsCSharpPassByValue(quux, corge, ref grault, ref garply); Console.WriteLine(quux[0]); // More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value. Console.WriteLine(corge.value); // For value types it is pure pass-by-value. Console.WriteLine(grault); // It also supports pass-by-reference if explicitly requested. Console.WriteLine(garply.value); // Pass-by-reference is supported for value types as well. } } 
+2
source share
 var a = new Number(10); x(a); alert(a); function x(n) { n = n + 2; // NOT VALID as this would essentially mean 10 = 10 + 2 since you are passing the 'value' of a and not 'a' itself } 

You need to write the following to make it work

 var a = new Number(10); x(a); alert(a); function x(n) { a = n + 2; // reassign value of 'a' equal to the value passed into the function plus 2 } 
0
source share

JavaScript parameter passing works similarly to Java passing. Individual values ​​are passed by value, but object attributes are passed by reference through their pointer values. The value itself will not be changed in the function, but the attributes of the object will be changed.

Consider the following code:

 function doThis(param1, param2) { param1++; if(param2 && param2.value) { param2.value++; } } var initialValue = 2; var initialObject = {value: 2}; doThis(initialValue, initialObject); alert(initialValue); //2 alert(initialObject.value); //3 

http://jsfiddle.net/bfm01b4x/

0
source share

All Articles