So as far as JS and Java are concerned the syntaxes of the two languages are very similar but the semantics between the two vary wildly even discounting browser weirdness.
but for simple things it's very similar. small algorithms and things like that
For simple things all languages are similar
okay, so here's a bet. I will write a bit of javascript code. very small, very simple.
You will try to write some mock Java that does the same thing.
I bet that you will find it harder to do
function upperCaseName(entity) {
return {...entity, name: entity.name.toUpperCase() }
}
const dog = { name: "Fido", favorite_toy: "Squeeks" }
const person { name: "Bob", majored_in: "Physics" , age: 30 }
upperCaseName(dog) // { name: "FIDO", favorite_toy: "Squeeks" }
upperCaseName(person) // { name: "BOB", majored_in: "Physics" , age: 30 }
Objects are a JS-specific thing, but... that should be doable in Java. won't look nice, won't behave well, but it'll be doable
oh so the thing that most libraries in JS use as their primary data representation are JS specific?
yes
in Java you'd use a POD for them
in JS you don't want that overhead, in Java it's kinda unavoidable
POD?
plain old data
You mean a class with getters and setters right? That won't work here.
Dynamic languages have a whole set of design patterns unique to their inherit flexibility in the same way Functional Languages like Haskell have a whole set of design patterns unique to their inherit restrictions.
Javascript is dynamic and weakly typed and Java is static and strongly typed. The second bit there is very important because it clues to the underlying semantics of the language.
yeah, of course.
also kinda working in Java:
import java.util.Map; import java.util.HashMap; public class Main { public static void main(String[] args) { System.out.println(upperCaseName(new HashMap<String, Object>() {{ put("name", "Fido"); put("favorite_toy", "Squeeks"); }})); } static Map<String, Object> upperCaseName(Map<String, Object> map) { if (map.containsKey("name") && map.get("name") instanceof String) { .put("name", ((String) map.get("name")).toUpperCase()); map} return map; } }
In Javascript saying class
has an insanely different meaning than in Javascript.
In java when you say class you are declaring a template for a concrete object to be created later. You are saying that your object will have these slots, that your object will have these methods that will work on said slots of data, and you define how the object will be constructed.
But in Javascript you aren't doing that. In Javascript you are actually creating an object.
That object is the "prototype" for new objects to be created from and you are saying "hey just copy this object"
that's the prototype, not the class
There is no such thing as the class Not in any form that isn't syntax sugar.
The main similarity between JS and Java is the syntax, which was done on purpose. Hence the misleading name of JavaScript.
The whole point was to look like Have at first glance but at its core JS is more a badly implemented lisp than anything else.
Now I am going to do the dog example in idiomatic java give me a few minutes
import java.util.Objects;
interface HasName<T extends HasName<T>> {
String getName();
withName(String name);
T }
class Dog implements HasName<Dog> {
private final String name;
private final String favoriteToy;
Dog(String name, String favoriteToy) {
.requireNonNull(name, "Name should not be null");
Objects.requireNonNull(favoriteToy, "Favorite Toy should not be null");
Objectsthis.name = name;
this.favoriteToy = favoriteToy;
}
@Override
public String getName() {
return this.name;
}
@Override
public Dog withName(String name) {
return new Dog(name, this.favoriteToy);
}
public String getFavoriteToy() {
return this.favoriteToy;
}
public Dog withFavoriteToy(String favoriteToy) {
return new Dog(this.name, favoriteToy);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
= (Dog) o;
Dog dog return Objects.equals(name, dog.name) &&
.equals(favoriteToy, dog.favoriteToy);
Objects}
@Override
public int hashCode() {
return Objects.hash(name, favoriteToy);
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", favoriteToy='" + favoriteToy + '\'' +
'}';
}
}
class Person implements HasName<Person> {
private String name;
private String majoredIn;
private int age;
Person(String name, String majoredIn, int age) {
.requireNonNull(name, "Name should not be null");
Objects.requireNonNull(majoredIn, "Majored In should not be null");
Objectsthis.name = name;
this.majoredIn = majoredIn;
this.age = age;
}
@Override
public String getName() {
return this.name;
}
@Override
public Person withName(String name) {
return new Person(name, this.majoredIn, this.age);
}
public String getMajoredIn() {
return this.majoredIn;
}
public Person withMajoredIn(String majoredIn) {
return new Person(this.name, majoredIn, this.age);
}
public int getAge() {
return this.age;
}
public Person withAge(int age) {
return new Person(this.name, this.majoredIn, age);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
= (Person) o;
Person person return age == person.age &&
.equals(name, person.name) &&
Objects.equals(majoredIn, person.majoredIn);
Objects}
@Override
public int hashCode() {
return Objects.hash(name, majoredIn, age);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", majoredIn='" + majoredIn + '\'' +
", age=" + age +
'}';
}
}
public class Main {
private static <T extends HasName<T>> T upperCaseName(HasName<T> entity) {
return entity.withName(entity.getName().toUpperCase());
}
public static void main(String[] args) {
= new Dog("Fido", "Squeeks");
Dog fido = new Person("Bob", "Physics", 30);
Person bob System.out.println("Before:");
System.out.println(fido);
System.out.println(bob);
= upperCaseName(fido);
Dog fidoUpper = upperCaseName(bob);
Person bobUpper
System.out.println("After:");
System.out.println(fidoUpper);
System.out.println(bobUpper);
}
}