Go for JavaScript Developers
A practical guide to understanding Go through familiar JavaScript patterns and concepts.
Variables & Constants
Variable Declaration
JavaScript:
let name = "John";
var age = 25;
const count = 10;
Go:
var name string = "John"
var age int = 25
const count int = 10
// Short declaration (only inside functions)
name := "John"
age := 25
Multiple Variables
JavaScript:
let x = 1, y = 2, z = 3;
const {name, age} = user;
Go:
var x, y, z int = 1, 2, 3
// Named return values
func getUser() (name string, age int) {
return "John", 25
}
Data Types
| Concept | JavaScript | Go |
|---|---|---|
| String | string | string |
| Number | number | int, int32, int64, float32, float64 |
| Boolean | boolean | bool |
| Array | array | slice or array |
| Object | object | struct |
| Function | function | func |
| Any Type | any | interface{} |
Structs vs Objects
JavaScript:
const user = {
name: "John",
age: 25,
email: "john@example.com"
};
user.name; // "John"
Go:
type User struct {
Name string
Age int
Email string
}
user := User{Name: "John", Age: 25, Email: "john@example.com"}
user.Name // "John"
Functions
Basic Functions
JavaScript:
function add(a, b) {
return a + b;
}
// Arrow function
const multiply = (a, b) => a * b;
Go:
func add(a int, b int) int {
return a + b
}
// Multiple return values
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
Function as First-Class Object
JavaScript:
const map = (arr, fn) => arr.map(fn);
const square = x => x * x;
map([1, 2, 3], square); // [1, 4, 9]
Go:
func map_(arr []int, fn func(int) int) []int {
result := make([]int, len(arr))
for i, v := range arr {
result[i] = fn(v)
}
return result
}
square := func(x int) int { return x * x }
map_([]int{1, 2, 3}, square) // [1, 4, 9]
Arrays & Slices
Collections
JavaScript:
let arr = [1, 2, 3];
arr.push(4);
arr.map(x => x * 2);
arr.filter(x => x > 2);
arr.length;
Go:
// Arrays (fixed size)
var arr [3]int = [3]int{1, 2, 3}
// Slices (dynamic)
slice := []int{1, 2, 3}
slice = append(slice, 4)
len(slice) // 4
// Iteration
for i, v := range slice {
fmt.Println(i, v)
}
Loops
For Loops
JavaScript:
// Traditional
for (let i = 0; i < 10; i++) {
console.log(i);
}
// forEach
[1, 2, 3].forEach(num => {
console.log(num);
});
// for...of
for (const item of array) {
console.log(item);
}
Go:
// Traditional for loop
for i := 0; i < 10; i++ {
fmt.Println(i)
}
// While loop
i := 0
for i < 10 {
fmt.Println(i)
i++
}
// Range loop (like for...of)
for _, item := range array {
fmt.Println(item)
}
// Break and continue
for i := 0; i < 10; i++ {
if i == 5 {
break
}
if i == 2 {
continue
}
}
Conditionals
if/else
JavaScript:
if (age >= 18) {
console.log("Adult");
} else if (age >= 13) {
console.log("Teen");
} else {
console.log("Child");
}
// Ternary
const status = age >= 18 ? "Adult" : "Child";
Go:
if age >= 18 {
fmt.Println("Adult")
} else if age >= 13 {
fmt.Println("Teen")
} else {
fmt.Println("Child")
}
// Short if
if err := doSomething(); err != nil {
log.Fatal(err)
}
Switch Statements
JavaScript:
switch (day) {
case "Monday":
console.log("Start of week");
break;
case "Friday":
console.log("End of week");
break;
default:
console.log("Midweek");
}
Go:
switch day {
case "Monday":
fmt.Println("Start of week")
case "Friday":
fmt.Println("End of week")
default:
fmt.Println("Midweek")
}
// Switch without expression
switch {
case age < 13:
fmt.Println("Child")
case age < 18:
fmt.Println("Teen")
default:
fmt.Println("Adult")
}
Error Handling
Exceptions vs Error Returns
JavaScript:
try {
riskyOperation();
} catch (error) {
console.error("Error:", error.message);
} finally {
cleanup();
}
function riskyOperation() {
throw new Error("Something went wrong");
}
Go:
// Go uses explicit error returns (no exceptions)
result, err := riskyOperation()
if err != nil {
log.Fatal("Error:", err)
}
func riskyOperation() (string, error) {
return "", errors.New("Something went wrong")
}
// Custom errors
type ValidationError struct {
Field string
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Message)
}
Maps (Objects/Dictionaries)
Key-Value Pairs
JavaScript:
const user = {
name: "John",
age: 25,
city: "NYC"
};
user.name; // "John"
user["age"]; // 25
delete user.city;
Go:
user := map[string]interface{}{
"name": "John",
"age": 25,
"city": "NYC",
}
user["name"] // "John"
value, ok := user["age"] // Check if key exists
delete(user, "city")
// Typed maps
scores := map[string]int{
"Alice": 95,
"Bob": 87,
}
Pointers
Memory References
JavaScript:
// JavaScript handles references automatically
let obj = {name: "John"};
let ref = obj;
ref.name = "Jane"; // Changes obj too
// Primitives are copied
let x = 5;
let y = x;
y = 10; // x is still 5
Go:
// Pointers are explicit
type User struct {
Name string
}
user := User{Name: "John"}
ptr := &user // Get pointer to user
ptr.Name = "Jane" // Changes user.Name
*ptr // Dereference pointer
// Function with pointer receiver (mutates original)
func (u *User) setName(name string) {
u.Name = name
}
// Function with value receiver (doesn't mutate)
func (u User) getName() string {
return u.Name
}
Interfaces
Type-based Polymorphism
JavaScript:
class Animal {
speak() {
throw new Error("speak() must be implemented");
}
}
class Dog extends Animal {
speak() {
return "Woof";
}
}
class Cat extends Animal {
speak() {
return "Meow";
}
}
Go:
// Interface definition
type Animal interface {
Speak() string
}
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return "Woof"
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return "Meow"
}
// Any type implementing Animal interface
func makeSound(a Animal) {
fmt.Println(a.Speak())
}
Goroutines vs Promises
Concurrency
JavaScript:
// Promises
Promise.all([
fetch('url1'),
fetch('url2')
]).then(results => {
console.log(results);
});
// Async/await
async function fetchData() {
try {
const result1 = await fetch('url1');
const result2 = await fetch('url2');
console.log(result1, result2);
} catch (error) {
console.error(error);
}
}
Go:
// Goroutines with channels
results := make(chan string, 2)
go func() {
results <- fetchData("url1")
}()
go func() {
results <- fetchData("url2")
}()
result1 := <-results
result2 := <-results
// WaitGroup for synchronization
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
// do work
}()
go func() {
defer wg.Done()
// do work
}()
wg.Wait()
Package Management
Imports
JavaScript:
import { add, subtract } from './math.js';
import React from 'react';
import * as utils from './utils.js';
Go:
import (
"fmt"
"errors"
"github.com/username/package"
)
// Using imported packages
fmt.Println("Hello")
err := errors.New("Error")
Methods vs Functions
Receivers
JavaScript:
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
area() {
return this.width * this.height;
}
}
const rect = new Rectangle(10, 20);
rect.area(); // 200
Go:
type Rectangle struct {
Width, Height float64
}
// Method (has receiver)
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// Function (no receiver)
func CalculateArea(width, height float64) float64 {
return width * height
}
rect := Rectangle{Width: 10, Height: 20}
rect.Area() // 200
Defer & Cleanup
Resource Cleanup
JavaScript:
try {
const file = openFile('data.txt');
const content = file.read();
console.log(content);
} finally {
file.close();
}
Go:
file, err := os.Open("data.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close() // Executes when function returns
content, _ := io.ReadAll(file)
fmt.Println(string(content))
// file.Close() is called automatically
Testing
Test Structure
JavaScript (Jest):
describe('Math operations', () => {
test('adds two numbers', () => {
expect(add(2, 3)).toBe(5);
});
});
Go:
// Filename: math_test.go
package mypackage
import "testing"
func TestAdd(t *testing.T) {
result := Add(2, 3)
if result != 5 {
t.Errorf("Expected 5, got %d", result)
}
}
// Run with: go test ./...
Key Differences Summary
| Aspect | JavaScript | Go |
|---|---|---|
| Type System | Dynamic | Static, strongly typed |
| Null Handling | null/undefined | nil (explicit) |
| Error Handling | Exceptions (try/catch) | Error returns |
| Concurrency | Promises/async-await | Goroutines/channels |
| Compilation | Interpreted/JIT | Compiled |
| Memory Management | Garbage collected | Garbage collected |
| Pointers | Implicit | Explicit |
| Inheritance | Prototype-based | Composition-based |
| Package Manager | npm/yarn | go modules |
Resources
Last updated: 2026-03-30