[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.javascript

Identity of values in Javascript

Steven D'Aprano

5/22/2015 12:48:00 PM

Hi, I'm a newbie when it comes to Javascript, and I'm trying to understand
some aspects of the language model. Please correct me if I'm wrong.

Javascript has two kinds of values, simple values or primitives, and
objects. There are three primitive types: number, string and boolean.
Primitives are implemented as simple machine types. Everything else is an
object.

var a = 23; // a primitive
var b = {}; // an object
var c = [1, 2] // arrays are objects too


I understand that for primitives, if I pass a value to a function,
Javascript uses pass by value: the value is copied. (This is the same
behaviour as, say, C or Pascal.) While accepting that on faith is fine, I'd
like to actually demonstrate it with some Javascript code.

In C or Pascal, I could use the "address of" operator to compare the value
inside the function with the value outside the function, to see if they
referred to the same memory location. In Javascript, I could use something
like this:


function test(arg) {
if (addr(arg) != addr(x)) {
return "copied"
}
else {
return "not copied"
}
}

x = 23;
print(test(x)); // I'm using the rhino shell.


except that there's no "addr" function that returns the address of a value.

In Ruby I would use "arg.equal? x", in Python I would use "arg is x", and in
Lua I would use "rawequal(arg, x)". Is there anything I can write in
Javascript to demonstrate that when I pass a primitive value into a
function, it is copied, but when I pass an object into the function, it is
not?


Thanks in advance,



--
Steven

34 Answers

ram

5/22/2015 4:52:00 PM

0

Steven D'Aprano <steve@pearwood.info> writes:
>Javascript has two kinds of values, simple values or primitives, and
>objects. There are three primitive types: number, string and boolean.

string
number
Boolean
null
undefined
symbol (new in ECMAScript 6)

>I understand that for primitives, if I pass a value to a function,
>Javascript uses pass by value: the value is copied. (This is the same
>behaviour as, say, C or Pascal.) While accepting that on faith is fine, I'd
>like to actually demonstrate it with some Javascript code.
>In C or Pascal, I could use the "address of" operator to compare the value
>inside the function with the value outside the function, to see if they
>referred to the same memory location. In Javascript, I could use something
>like this:

A value does not have an address. Such a value is known as
an »rvalue« in C++. With values, it makes no sense to make
this distinction between »pass by value" and "pass by reference".

> Is there anything I can write in
>Javascript to demonstrate that when I pass a primitive value into a
>function, it is copied, but when I pass an object into the function, it is
>not?

In the case of a value, you show it by showing that it just works.

You can show that objects are not copied in this case
by showing alias effects.

function modify( object ){ object.field = 5; }
function main()
{ var object = {}; modify( object ); console.log( object.field ); }
main();

ram

5/22/2015 5:14:00 PM

0

Supersedes: <pass-20150522184523@ram.dialup.fu-berlin.de>

Steven D'Aprano <steve@pearwood.info> writes:
>Javascript has two kinds of values, simple values or primitives, and
>objects. There are three primitive types: number, string and boolean.

string
number
boolean
null
undefined
symbol (new in ECMAScript 6)

>I understand that for primitives, if I pass a value to a function,
>Javascript uses pass by value: the value is copied. (This is the same
>behaviour as, say, C or Pascal.) While accepting that on faith is fine, I'd
>like to actually demonstrate it with some Javascript code.
>In C or Pascal, I could use the "address of" operator to compare the value
>inside the function with the value outside the function, to see if they
>referred to the same memory location. In Javascript, I could use something
>like this:

A value does not have an address. Expressions for such
values are known as »prvalues« in C++. With (pr)values,
it makes no sense to make this distinction between »pass by
value" and "pass by reference". One might also say it this
way: "The value of a prvalue doubles as it's reference."

> Is there anything I can write in
>Javascript to demonstrate that when I pass a primitive value into a
>function, it is copied, but when I pass an object into the function, it is
>not?

In the case of a value, you show it by showing that it just works.

You can show that objects are not copied in this case
by showing alias effects.

function modify( object ){ object.field = 5; }
function main()
{ var object = {}; modify( object ); console.log( object.field ); }
main();

Ben Bacarisse

5/22/2015 6:17:00 PM

0

Steven D'Aprano <steve@pearwood.info> writes:

> Hi, I'm a newbie when it comes to Javascript, and I'm trying to understand
> some aspects of the language model. Please correct me if I'm wrong.
>
> Javascript has two kinds of values, simple values or primitives, and
> objects. There are three primitive types: number, string and boolean.
> Primitives are implemented as simple machine types. Everything else is an
> object.

The ECMAScript types are named with capitals, and there are a couple
more (Null and Undefined) but that's neither here nor there as far as
your point goes. Also I'm not sure I'd say that String is implemented
as a simple machine type -- it's a relatively complex type compared to,
say, Number, -- but, again, that's not your point.

> var a = 23; // a primitive
> var b = {}; // an object
> var c = [1, 2] // arrays are objects too
>
> I understand that for primitives, if I pass a value to a function,
> Javascript uses pass by value: the value is copied. (This is the same
> behaviour as, say, C or Pascal.) While accepting that on faith is fine, I'd
> like to actually demonstrate it with some Javascript code.
>
> In C or Pascal, I could use the "address of" operator to compare the value
> inside the function with the value outside the function, to see if they
> referred to the same memory location.

In C and in Pascal values don't have addresses so you can't tell if a
value is copied by taking the address of anything.

In C, you can be certain that the object (using the C term) named by the
parameter has a unique address distinct from that of all of the objects
during its lifetime, but that's it. You know you get a copied value
because of the way the semantics of function calling is defined.

Informally, I'd describe ECMAScript argument passing as call by sharing
(as in Python) because that's how it behaves. The full specification is
in ECMA 262 edition 5.1 (there's a new version, 6, on the way). People
more expert than I will step in to say where (if anywhere) the corner
cases are that make this informal description untrue.

> In Javascript, I could use something
> like this:
>
>
> function test(arg) {
> if (addr(arg) != addr(x)) {
> return "copied"
> }
> else {
> return "not copied"
> }
> }
>
> x = 23;

This is a little odd in ECMAScript. Put a 'var' in front to make a new
named variable. Otherwise you are adding (or modifying) the 'x'
property to the global object.

> print(test(x)); // I'm using the rhino shell.

<snip>
--
Ben.

ram

5/22/2015 6:30:00 PM

0

Supersedes: <pass-20150522190529@ram.dialup.fu-berlin.de>

Steven D'Aprano <steve@pearwood.info> writes:
>Javascript has two kinds of values, simple values or primitives, and
>>objects. There are three primitive types: number, string and boolean.

String
Number
Boolean
Null
Undefined
Symbol (new in ECMAScript 6)

>I understand that for primitives, if I pass a value to a function,
>Javascript uses pass by value: the value is copied. (This is the same
>behaviour as, say, C or Pascal.) While accepting that on faith is fine, I'd
>like to actually demonstrate it with some Javascript code.
>In C or Pascal, I could use the "address of" operator to compare the value
>inside the function with the value outside the function, to see if they
>referred to the same memory location. In Javascript, I could use something
>like this:

A value does not have an address. Expressions for such
values are known as »prvalues« in C++. With (pr)values,
it makes no sense to make this distinction between »pass by
value" and "pass by reference". One might also say it this
way: "The value of a prvalue doubles as it's reference."

> Is there anything I can write in
>Javascript to demonstrate that when I pass a primitive value into a
>function, it is copied, but when I pass an object into the function, it is
>not?

In the case of a value, you show it by showing that it just works.

You can show that objects are not copied in this case
by showing alias effects.

function modify( object ){ "use strict"; object.field = 5; }
function main()
{ "use strict"; var object = {}; modify( object );
console.log( object.field ); }
main();

Steven D'Aprano

5/22/2015 7:02:00 PM

0

On Sat, 23 May 2015 04:17 am, Ben Bacarisse wrote:

> Steven D'Aprano <steve@pearwood.info> writes:
>
>> Hi, I'm a newbie when it comes to Javascript, and I'm trying to
>> understand some aspects of the language model. Please correct me if I'm
>> wrong.
>>
>> Javascript has two kinds of values, simple values or primitives, and
>> objects. There are three primitive types: number, string and boolean.
>> Primitives are implemented as simple machine types. Everything else is an
>> object.
>
> The ECMAScript types are named with capitals, and there are a couple
> more (Null and Undefined) but that's neither here nor there as far as
> your point goes. Also I'm not sure I'd say that String is implemented
> as a simple machine type -- it's a relatively complex type compared to,
> say, Number, -- but, again, that's not your point.

True :-) but thanks for the correction anyway.

As I said, I'm new to Javascript, and I keep finding sources that refer to
(say) lower case string, and distinguish it from String. E.g.:

https://developer.mozilla.org/en-US/docs/Glossary...


[quote]
In JavaScript, there are 6 primitive data types:

string
[...]
String for the string primitive.
[end quote]


>> var a = 23; // a primitive
>> var b = {}; // an object
>> var c = [1, 2] // arrays are objects too
>>
>> I understand that for primitives, if I pass a value to a function,
>> Javascript uses pass by value: the value is copied. (This is the same
>> behaviour as, say, C or Pascal.) While accepting that on faith is fine,
>> I'd like to actually demonstrate it with some Javascript code.
>>
>> In C or Pascal, I could use the "address of" operator to compare the
>> value inside the function with the value outside the function, to see if
>> they referred to the same memory location.
>
> In C and in Pascal values don't have addresses so you can't tell if a
> value is copied by taking the address of anything.

I beg to differ. Pascal has the @ operator, which returns the address of the
variable currently holding the value you care about. Admittedly it's not
standard Pascal, but it is available in a number of popular compilers. C
has the & operator. If you want to argue that they return the address of
the variable, not the value, I won't disagree, but state that for my
purposes that is fine.


> In C, you can be certain that the object (using the C term) named by the
> parameter has a unique address distinct from that of all of the objects
> during its lifetime, but that's it. You know you get a copied value
> because of the way the semantics of function calling is defined.

Yes, and you can confirm it by comparing the address of the function formal
parameter and the address of the variable being used as argument. E.g.
given a function foo with formal parameter a, and a variable b in an
enclosing scope, if I call foo(b), pass by value semantics require that the
addresses &a and &b will be different.


> Informally, I'd describe ECMAScript argument passing as call by sharing
> (as in Python) because that's how it behaves.

That's what I expected, but I've found so many places claiming that
Javascript uses call by value for "simple types" and call by reference
for "reference types" that I wanted to see for myself.

(By the way, I've seen similar confusion and abuse of terminology in the
Ruby, Python and Java camps too.)


> The full specification is
> in ECMA 262 edition 5.1 (there's a new version, 6, on the way). People
> more expert than I will step in to say where (if anywhere) the corner
> cases are that make this informal description untrue.
>
>> In Javascript, I could use something
>> like this:
>>
>>
>> function test(arg) {
>> if (addr(arg) != addr(x)) {
>> return "copied"
>> }
>> else {
>> return "not copied"
>> }
>> }
>>
>> x = 23;
>
> This is a little odd in ECMAScript. Put a 'var' in front to make a new
> named variable. Otherwise you are adding (or modifying) the 'x'
> property to the global object.

Ah, thanks again for the correction.

I only need to use the var declaration once, correct? If I say:

var x = 23;

then later

x = 42;

the second assignment applies to the same x variable as the first. Correct?




--
Steven

ram

5/22/2015 7:08:00 PM

0

Steven D'Aprano <steve@pearwood.info> writes:

>On Sat, 23 May 2015 04:17 am, Ben Bacarisse wrote:

>>In C and in Pascal values don't have addresses so you can't tell if a
¯¯¯¯¯¯
>>value is copied by taking the address of anything.

>I beg to differ. Pascal has the @ operator, which returns the address of the

>variable currently holding the value you care about.
¯¯¯¯¯¯¯¯

Steven D'Aprano

5/22/2015 7:20:00 PM

0

On Sat, 23 May 2015 03:14 am, Stefan Ram wrote:

> Supersedes: <pass-20150522184523@ram.dialup.fu-berlin.de>
>
> Steven D'Aprano <steve@pearwood.info> writes:
>>Javascript has two kinds of values, simple values or primitives, and
>>objects. There are three primitive types: number, string and boolean.
>
> string
> number
> boolean
> null
> undefined
> symbol (new in ECMAScript 6)

Thanks for the correction.


>>I understand that for primitives, if I pass a value to a function,
>>Javascript uses pass by value: the value is copied. (This is the same
>>behaviour as, say, C or Pascal.) While accepting that on faith is fine,
>>I'd like to actually demonstrate it with some Javascript code.
>>In C or Pascal, I could use the "address of" operator to compare the value
>>inside the function with the value outside the function, to see if they
>>referred to the same memory location. In Javascript, I could use something
>>like this:
>
> A value does not have an address.

Numbers in Javascript are IEEE 754 64-bit floating point quantities, so if I
do "var x = 23;" the 64-bit float with value 23.0 must be somewhere.
Perhaps you mean that the address is unavailable to Javascript code?



> Expressions for such
> values are known as »prvalues« in C++. With (pr)values,
> it makes no sense to make this distinction between »pass by
> value" and "pass by reference".

I know very little about C++, but speaking more generally, pass by value and
pass by reference have VERY different semantics and it is nonsense to say
that there is no distinction between them. Pass by reference has strict
requirements: the argument passed must be an actual variable, not an
arbitrary expression or constant (early Fortran compilers were notorious
for a bad bug where you could literally change the value of numeric
constants by passing then by reference), and the function parameter is
treated as an alias to that variable for assignment. Pass by value is very
different.


> One might also say it this
> way: "The value of a prvalue doubles as it's reference."

When I assign a value to a variable:

var x = 42;

the value of x that I am talking about is 42, not some reference to 42.


>> Is there anything I can write in
>>Javascript to demonstrate that when I pass a primitive value into a
>>function, it is copied, but when I pass an object into the function, it is
>>not?
>
> In the case of a value, you show it by showing that it just works.

What does "it just works" mean? What's "it"? That I can pass an argument to
a function?

Unfortunately, "I can pass arguments to functions" works equally well
whether the calling convention is by value, by name, by reference, by need,
by sharing, or something else. The only calling convention that can be
ruled out is call by reference, because I can pass expressions as arguments
(pass by reference parameters must be lvalues).


> You can show that objects are not copied in this case
> by showing alias effects.
>
> function modify( object ){ object.field = 5; }
> function main()
> { var object = {}; modify( object ); console.log( object.field ); }
> main();


Yes, I'm aware of that. But I'm asking specifically about primitive types,
not objects. Using rhino:


js> function modify( object ){
> object.field = 5;
> print(object.field);
> }
js> x = 23;
23
js> modify(x);
undefined


So your test doesn't work here.



--
Steven

Steven D'Aprano

5/22/2015 7:26:00 PM

0

On Sat, 23 May 2015 05:08 am, Stefan Ram wrote:

> Steven D'Aprano <steve@pearwood.info> writes:
>
>>On Sat, 23 May 2015 04:17 am, Ben Bacarisse wrote:
>
>>>In C and in Pascal values don't have addresses so you can't tell if a
> ¯¯¯¯¯¯
>>>value is copied by taking the address of anything.
>
>>I beg to differ. Pascal has the @ operator, which returns the address of
>>the
>
>>variable currently holding the value you care about.
> ¯¯¯¯¯¯¯¯

You deleted the part where I said:

"If you want to argue that they return the address of
the variable, not the value, I won't disagree, but state that for my
purposes that is fine."



--
Steven

ram

5/22/2015 7:38:00 PM

0

Steven D'Aprano <steve@pearwood.info> writes:
>On Sat, 23 May 2015 03:14 am, Stefan Ram wrote:
>>A value does not have an address.
>When I assign a value to a variable:
>var x = 42;
>the value of x that I am talking about is 42, not some reference to 42.

Variables are not values.

Do you want to talk about variables or values now?

>>In the case of a value, you show it by showing that it just works.
>What does "it just works" mean? What's "it"? That I can pass an argument to
>a function?
>>>Is there anything I can write in Javascript to demonstrate
>>>that when I pass a primitive value into a function, it is
>>>copied, but when I pass an object into the function, it is
>>>not?

When you have got 17, there is no way to observe whether
it's the »original 17« or a »copy of 17«. So, this
distinction does not make sense in such a case.

When you pass a value to a function, you cannot tell whether
the value is copied or referenced, because are not able to
observe the difference between a copy and a reference in the
case of primitive values. So you just can show that you can
pass a value and then observe (use) it in the function:

function f( primitiveValue ){ "use strict"; console.log( primitiveValue ); }
function main(){ "use strict"; f( 17 ); }
main();

ram

5/22/2015 7:41:00 PM

0

ram@zedat.fu-berlin.de (Stefan Ram) writes:
>Variables are not values.

... of course, one can use a variable to express a
value in an expression.

I wanted to say that the /concept of a variable/ is
different from the /concept of a value/.