When you are working with different languages at the same time, it is important to note that while most languages are based on C, each langauge has its own set of rules and paradigms associated with it that makes similar conventions different.
Java and JavaScript, while having Java in common, are completely different languages1. As such, the way they deal with primitive values2, functions and methods, arguments and parameters, differ as well.
Java is an Object Oriented Programming language which basically means creating objects as part of a class, instantiating the object and adding methods to the object to actually do things with the newly created objects. You can then make your code more modular by adding and calling functions that manipulate the code in some way.3
You can create an object such as:
public class Dog {
int dogAge;
public Dog(string name) {
System.out.println("My dog's name is " + name " .");
}
public void setAge (int age) {
dogAge = age;
}
public int getAge() {
System.out.println("My dog is " + dogAge + " years old");
return dogAge;
}
public static void main (String []args) {
/* Create an object using the new keyword */
Dog myDog = new Dog("Max");
myDog.setAge(11); // setAge is a class method on the object Dog
myDog.getAge();
System.out.println(myDog.dogAge);
}
}
Here we have a class and a constructor, a new object Dog
with a few getter and setter methods on the Dog
object.
This is standard Java OOP stuff. JavaScript isn’t an OOP language, it is a prototypal language which creates object prototypes in order to extend objects through prototypal inheritance instead of classical inheritance, like Java.4
Objects in JavaScript are not created the same way as in Java. At least not technically, and this:
function Car() {
const car1 = new Car();
}
should be avoided.5
We can create an object literal such as:
const myObject {
foo: 'bar',
car: 'Mazda',
age: 38
}
and add methods onto the object such as:
myObject.car = 'Honda';
and pass them to other methods like console.log:
console.log(myObject.car);
The only thing you can pass by value in JavaScript are primitive data types.
Passing by value means that you have two variables in memory that are assigned to one another. For instance:
var a;
var b = 8;
var a = b;
console.log(b); // will return 8
What’s happening when we pass these primitives by value, we are making a copy of the value of the variable b
stored in memory, say at address 0x001 and assigning it to a
stored at 0x002. Both a
and `b mirror each other as they are just copies of one another. This is what is meant when we say we are passing by value in JavaScript.
Take this bit of code:
int y = 10;
changeMeToSix (y);
System.out.println(y);
// [...some code]
void changeMeToSix (int x) {
x = 6;
}
This doesn’t print 6. It prints 10. Why? Because only the value 10 was passed into the method, not the variable itself.
Another example:
Dog myDog;
This is not actually a dog but a pointer to the Dog instance in memory. So if we have:
public void foo (Dog yourDog) {
yourDog.setName("Sparky");
yourDog = new Dog("Max");
yourDog.setName("Jeffie");
}
Let’s say the parameter yourDog
is at memory address 0x001.
The first line is followed to the Dog
it points to, which is the Dog
object at 0x001. That dog is asked to change names to Sparky, at the same address of 0x001.
In the second line, a new Dog
is created at a different address, say, 0x006. We assign the yourDog
param to the memory address 0x006.
In the last line, yourDog is followed to the new Dog
it points to in 0x006. That Dog
changes his name to Jeffie
. Then it returns.
myDog
didn’t change. myDog
is a pointer in memory that points to the original address, 0x001, not an actual Dog
.
You can pass references to parameters by value and not the actual references themselves.
Passing by reference in JavaScript can only happen to objects. This includes functions as functions are first-class objects in JavaScript.6
Passing by reference involves having two references point to the same object in memory. This means you can mutate and object or function by assigning it to another object or passing it as a parameter to a function. Take this code:
// by reference (all objects (including functions))
const greet = {
greeting: 'hi'
};
const greet1;
greet1 = greet;
greet.greeting = 'hello'; // mutates to hello
console.log(greet);
console.log(greet1);
// by reference (even as parameters)
function changeGreeting(obj) {
obj.greeting = "What's up?"; // mutates to What's Up
}
changeGreeting(greet1);
console.log(greet);
console.log(greet1);
// equals operator sets up new memory address
greet = {
greeting: 'Yo'
};
console.log(greet); // Mutates to Yo
console.log(greet1);
…and so on.
Understanding the difference between pass by value and pass by reference is key to understanding how JavaScript objects and primitives work.
You cannot pass by reference in Java. As Jon Skeet puts it:
Pass by reference mixes inputs and outputs of code. This is the fundamental problem with the technique. In Java, a programmer can assume that variables will not change their value when passed as parameters to a method. In languages with pass by reference semantics, this basic assumption cannot be made.
Pass by reference confuses the interface to a method. Methods written using pass-by-reference semantics can have extremely complex interfaces that are difficult for client programmers to learn and understand.
Excluding pass by reference was a design choice. It fills a need in some languages, like JavaScript but can present problems in others.
Sorry about the length! If you have anything to add, leave a comment down below. Let me know if I am wrong or off-base. I don’t mind.
UPDATE: I suppose you can’t redeclare a variable with let in the example of pass by value in JS. So I went to the console, did some console-fu and decided to use var
though it is dated. Still learning ES6.
UPDATE 2: So I learned you cannot pass by reference in JavaScript though that is exactly what I was taught, albeit incorrectly. You can pass a reference to another object, but you cannot pass by reference in JavaScript.
Both languages are based on C, however. ↩
Both Java and JavaScript have primitive types. Java has strongly typed primitive values. See this post for Java data types. ↩
Technically, in Java, you can use method and function interchangeably but I really don’t like doing that. See this answer. ↩
Eric Elliott has talked about this a lot. Check it out for the differences inheritance between the two languages. ↩
This is creating an object using a JavaScript constructor and the new
keyword, mimicking OOP inheritance in JavaScript. Douglas Crockford recommends that you avoid it. ↩
More in another post. ↩