forked from goplus/xgo
-
Notifications
You must be signed in to change notification settings - Fork 4
JavaScript vs. Go Statement
xushiwei edited this page Apr 5, 2026
·
1 revision
| 特性 | JavaScript | Go |
|---|---|---|
| 声明并赋值 |
let a = 1 / const a = 1
|
var a int = 1 / a := 1
|
| 仅声明 |
let a → 值为 undefined
|
var a int → 零值 0
|
| 常量 |
const PI = 3.14(块级,不可重赋值) |
const PI = 3.14(编译期常量) |
| 多变量声明 | let a = 1, b = 2 |
var a, b int = 1, 2 / a, b := 1, 2
|
| 块级作用域 |
let / const 有块级作用域 |
所有变量均为块级作用域 |
| 变量提升 |
var 存在提升,let/const 不提升 |
无变量提升 |
| 未使用变量 | 允许(无警告或仅 lint 警告) | 编译错误,必须使用 |
// JS
let x; // undefined
const y = 42;
var z = "hoisted";// Go
var x int // 零值 0
const y = 42
a, b := 1, 2 // 短变量声明,至少一个新变量| 特性 | JavaScript | Go |
|---|---|---|
| 基本 if | if (cond) { } |
if cond { }(条件无需括号) |
| if-else | if (cond) { } else { } |
if cond { } else { } |
| else-if | else if (cond) { } |
else if cond { } |
| 初始化语句 | 不支持 |
if x := f(); x > 0 { }(init; cond) |
| switch | switch (expr) { case v: ... } |
switch expr { case v: ... } |
| switch 穿透 | 默认穿透,需 break 阻止 |
默认不穿透,需 fallthrough 强制穿透 |
| switch 无表达式 | 不支持 | 支持,等价于 if-else 链 |
| switch 多值 case | 不支持(需多个 case) |
case 1, 2, 3: 支持多值 |
| switch 初始化语句 | 不支持 | switch x := f(); { ... } |
| 类型 switch | 不支持 | switch v := x.(type) { case int: ... } |
// JS switch 默认穿透
switch (n) {
case 1:
console.log("one");
break; // 必须手动 break
case 2:
console.log("two");
}// Go switch 默认不穿透
switch n {
case 1:
fmt.Println("one") // 自动 break
case 2, 3:
fmt.Println("two or three")
default:
fmt.Println("other")
}
// Go 类型 switch
switch v := x.(type) {
case int:
fmt.Println("int:", v)
case string:
fmt.Println("string:", v)
}| 特性 | JavaScript | Go |
|---|---|---|
| 基本循环 | for (init; cond; post) { } |
for init; cond; post { } |
| while 风格 | while (cond) { } |
for cond { }(Go 无 while 关键字) |
| 无限循环 | while (true) { } |
for { }(最简写法) |
| do-while | do { } while (cond) |
不支持,用 for { ... if !cond { break } }
|
| for-of(迭代值) | for (const v of arr) { } |
for _, v := range arr { } |
| for-in(迭代键) | for (const k in obj) { } |
for k := range m { }(map) |
| range 同时取键值 |
arr.entries() / Object.entries()
|
for i, v := range arr { } |
| 带标签的 break | outer: for(...) { break outer; } |
outer: for { break outer } |
| 带标签的 continue | outer: for(...) { continue outer; } |
outer: for { continue outer } |
break |
跳出当前循环或 switch | 跳出当前循环、switch 或 select |
continue |
跳过本次迭代 | 跳过本次迭代 |
// JS
for (let i = 0; i < 3; i++) { }
while (cond) { }
do { } while (cond);
for (const [i, v] of arr.entries()) { }
for (const k in obj) { }// Go
for i := 0; i < 3; i++ { }
for cond { } // while
for { } // 无限循环
for i, v := range arr { }
for k, v := range m { } // map
for k := range m { } // 仅键| 特性 | JavaScript | Go |
|---|---|---|
| 函数声明 | function fn(a, b) { return a + b } |
func fn(a, b int) int { return a + b } |
| 参数类型 | 无需声明 | 必须声明 |
| 返回值类型 | 无需声明 | 必须声明(无返回值写 func fn() ) |
| 多返回值 | 不支持(用数组/对象) | func fn() (int, error) { } |
| 命名返回值 | 不支持 | func fn() (result int, err error) { } |
| 可变参数 | function fn(...args) { } |
func fn(args ...int) { } |
| 函数提升 |
function 声明会提升 |
无提升,声明顺序无所谓(包级) |
| 匿名函数 | const fn = function() { } |
fn := func() { } |
| 箭头函数 | const fn = (a, b) => a + b |
无,用普通匿名函数 |
| 立即执行 | (() => { })() |
func() { }() |
| 闭包 | 支持 | 支持 |
| 方法 |
class 中定义 / 原型挂载 |
func (r Receiver) Method() { } |
// JS
function add(a, b) { return a + b; }
const mul = (a, b) => a * b;// Go
func add(a, b int) int { return a + b }
// 多返回值
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}| 特性 | JavaScript | Go |
|---|---|---|
| 单值返回 | return expr |
return expr |
| 多值返回 | 不支持(返回数组/对象) | return val, err |
| 空返回 |
return(返回 undefined) |
return(命名返回值时裸返回) |
| 无返回值函数 | 无需 return | 无需 return(void 对应无返回类型) |
| 特性 | JavaScript | Go |
|---|---|---|
| 抛出异常 | throw new Error("msg") |
无异常,返回 error 值 |
| 捕获异常 | try { } catch (e) { } finally { } |
无 try-catch,用 if err != nil { }
|
| 错误传递 | 异常自动向上冒泡 | 显式返回并检查 error
|
| panic | 无对应(类似未捕获异常) |
panic("msg")(不可恢复的错误) |
| recover | 无 |
recover()(在 defer 中捕获 panic) |
| finally | finally { } |
defer(函数返回前执行) |
// JS
try {
const data = JSON.parse(str);
} catch (e) {
console.error(e.message);
} finally {
cleanup();
}// Go
data, err := strconv.Atoi(str)
if err != nil {
log.Println(err)
return
}
// defer 类似 finally
defer cleanup()
// panic + recover
defer func() {
if r := recover(); r != nil {
fmt.Println("recovered:", r)
}
}()
panic("something went wrong")| 特性 | JavaScript | Go |
|---|---|---|
| 延迟执行 | 无 defer,用 finally 或回调 |
defer fn()(函数返回前按 LIFO 执行) |
| 资源自动释放 |
try-finally / using(ES2023) |
defer f.Close() |
| 多个 defer | — | 按后进先出(LIFO)顺序执行 |
// Go defer LIFO
func main() {
defer fmt.Println("third")
defer fmt.Println("second")
defer fmt.Println("first")
// 输出:first → second → third
}| 特性 | JavaScript | Go |
|---|---|---|
| 并发启动 |
setTimeout / Promise / async-await
|
go fn()(goroutine,极轻量) |
| channel 发送 | 无 | ch <- value |
| channel 接收 | 无 | value := <-ch |
| 多路复用 | Promise.race() |
select { case <-ch1: ... case <-ch2: ... } |
| select default | 无 |
select { case ...: default: ... }(非阻塞) |
// Go goroutine + channel
ch := make(chan int)
go func() { ch <- 42 }()
v := <-ch
// select 多路复用
select {
case msg := <-ch1:
fmt.Println("ch1:", msg)
case msg := <-ch2:
fmt.Println("ch2:", msg)
default:
fmt.Println("no message")
}| 特性 | JavaScript | Go |
|---|---|---|
| 模块声明 | 无需(文件即模块) |
package main(每文件必须声明) |
| 导入 |
import { fn } from "./mod" / import mod from "./mod"
|
import "fmt" / import alias "pkg"
|
| 导出 |
export / export default
|
首字母大写即导出(无关键字) |
| 批量导入 | import * as ns from "./mod" |
import ( "fmt"; "os" )(分组写法) |
| 忽略导入 | 无 |
import _ "pkg"(仅执行 init) |
| 别名导入 | import { fn as myFn } |
import alias "pkg" |
| 动态导入 | import("./mod").then(...) |
无(编译时静态确定) |
Go 有丰富的类型声明语句,JS 无对应概念(TypeScript 除外):
// 结构体
type Person struct {
Name string
Age int
}
// 接口
type Animal interface {
Speak() string
}
// 类型别名
type Celsius float64
type StringSlice = []string // 别名(=)
// 函数类型
type Handler func(w http.ResponseWriter, r *http.Request)| 特性 | JavaScript | Go |
|---|---|---|
| 标签定义 | label: |
label: |
| break 到标签 | break label |
break label |
| continue 到标签 | continue label |
continue label |
| goto | 不支持 |
goto label(同函数内跳转) |