跳转到正文
ygjoon
返回

Kotlin/JS 基础语法与类型映射

编辑文章

Kotlin/JS 语法概述

Kotlin/JS 继承了标准 Kotlin 的大部分语法特性,但由于目标平台是 JavaScript,某些特性和行为会有所不同。理解这些差异对于高效使用 Kotlin/JS 至关重要。

基本语法保持不变

Kotlin/JS 支持标准 Kotlin 的核心语法:

// 变量声明
val name: String = "Kotlin/JS"
var count: Int = 0

// 函数定义
fun greet(name: String): String {
    return "Hello, $name!"
}

// 类定义
class User(val name: String, var age: Int) {
    fun isAdult(): Boolean = age >= 18
}

// 条件语句
val message = if (count > 0) "Count is positive" else "Count is zero or negative"

// 循环
for (i in 1..5) {
    println("Iteration $i")
}

类型系统与映射

基本类型映射

Kotlin/JS 将 Kotlin 的基本类型映射到 JavaScript 的对应类型:

Kotlin 类型JavaScript 类型说明
Intnumber32 位整数
Doublenumber64 位浮点数
Floatnumber32 位浮点数
Booleanboolean布尔值
Stringstring字符串
Charstring单字符字符串
Array<T>Array数组
List<T>Array只读数组
MutableList<T>Array可变数组

类型映射示例

// Kotlin代码
val number: Int = 42
val pi: Double = 3.14159
val flag: Boolean = true
val text: String = "Hello Kotlin/JS"
val chars: CharArray = charArrayOf('K', 'o', 't')
val numbers: Array<Int> = arrayOf(1, 2, 3, 4, 5)

// 生成的JavaScript代码(简化版)
var number = 42;
var pi = 3.14159;
var flag = true;
var text = "Hello Kotlin/JS";
var chars = ['K', 'o', 't'];
var numbers = [1, 2, 3, 4, 5];

特殊类型处理

Any 类型

在 Kotlin/JS 中,Any类型映射到 JavaScript 的Object:

fun processValue(value: Any): String {
    return when (value) {
        is String -> "String: $value"
        is Number -> "Number: $value"
        else -> "Unknown type"
    }
}

Unit 类型

Unit类型在 JavaScript 中表示为undefined:

fun doSomething(): Unit {
    println("Doing something")
    // 隐式返回Unit
}

// 生成的JavaScript
function doSomething() {
    println("Doing something");
    // 没有显式返回,返回undefined
}

Nothing 类型

Nothing类型用于表示永远不会返回的函数:

fun throwError(message: String): Nothing {
    throw Error(message)
}

集合类型的转换与操作

Kotlin 集合与 JavaScript 数组

Kotlin/JS 中的集合类型在运行时被转换为 JavaScript 数组:

// Kotlin代码
val list: List<String> = listOf("Apple", "Banana", "Orange")
val mutableList: MutableList<Int> = mutableListOf(1, 2, 3)

// 集合操作
val filtered = list.filter { it.startsWith("A") }
val transformed = mutableList.map { it * 2 }

// 生成的JavaScript(简化)
var list = ["Apple", "Banana", "Orange"];
var mutableList = [1, 2, 3];

var filtered = list.filter(function(it) { return it.startsWith("A"); });
var transformed = mutableList.map(function(it) { return it * 2; });

集合操作的性能考虑

在 Kotlin/JS 中,某些集合操作可能比原生 JavaScript 慢,因为需要额外的函数调用开销:

// 性能较好的方式
val numbers = arrayOf(1, 2, 3, 4, 5)
var sum = 0
for (num in numbers) {
    sum += num
}

// 性能较差的方式(但更函数式)
val sum2 = numbers.reduce { acc, num -> acc + num }

空安全在 JavaScript 环境中的处理

可空类型

Kotlin 的空安全特性在 JavaScript 环境中通过编译时检查和运行时检查实现:

// 可空类型声明
val nullableString: String? = null
val nonNullString: String = "Hello"

// 安全调用
val length = nullableString?.length ?: 0

// 强制解包(会抛出异常)
val actualLength = nullableString!!.length

生成的 JavaScript 代码

// Kotlin代码
fun processNullable(text: String?): Int {
    return text?.length ?: 0
}

// 生成的JavaScript代码
function processNullable(text) {
    return text != null ? text.length : 0;
}

平台类型与 JavaScript 互操作

当与 JavaScript 代码交互时,可能会遇到平台类型:

// 假设这是一个JavaScript函数的声明
external fun jsFunction(): String

// 调用时需要处理可能的null值
val result = jsFunction()
val safeResult = result ?: "default"

类型检查与转换技巧

is 和 as 操作符

fun processValue(value: Any): String {
    return when {
        value is String -> "String length: ${value.length}"
        value is Int -> "Int value: $value"
        value is Array<*> -> "Array size: ${value.size}"
        else -> "Unknown type: ${value::class.simpleName}"
    }
}

// 安全转换
val stringValue: String? = value as? String

智能类型转换

fun demonstrateSmartCast(value: Any) {
    if (value is String) {
        // 在这个块中,value被智能转换为String类型
        println("Uppercase: ${value.toUpperCase()}")
    }

    if (value is List<*>) {
        // 在这个块中,value被智能转换为List
        println("List size: ${value.size}")
    }
}

标准库函数在 JS 环境中的使用

字符串操作

// Kotlin字符串函数
val text = "Hello, Kotlin/JS!"
val words = text.split(" ", ",")
val joined = words.joinToString("-")
val replaced = text.replace("Hello", "Hi")

// 生成的JavaScript(简化)
var text = "Hello, Kotlin/JS!";
var words = text.split(" ", ",");
var joined = words.joinToString("-");
var replaced = text.replace("Hello", "Hi");

数组操作

val numbers = intArrayOf(1, 2, 3, 4, 5)
val doubled = numbers.map { it * 2 }
val sum = numbers.sum()
val filtered = numbers.filter { it % 2 == 0 }

范围和序列

// 范围操作
val range = 1..10
val evenNumbers = range.filter { it % 2 == 0 }

// 序列操作(惰性求值)
val lazySequence = sequence {
    for (i in 1..100) {
        if (i % 7 == 0) yield(i)
    }
}

JavaScript 特有的类型和概念

dynamic 类型

Kotlin/JS 提供了dynamic类型来与动态 JavaScript 代码交互:

fun processDynamic(obj: dynamic) {
    // 可以访问任何属性,编译时不会检查
    println(obj.someProperty)

    // 可以调用任何方法
    obj.someMethod("argument")

    // 类型转换
    val name: String = obj.name
    val age: Int = obj.age
}

js()函数

js()函数允许在 Kotlin 代码中嵌入 JavaScript 代码片段:

fun getCurrentUrl(): String = js("window.location.href")

fun showAlert(message: String): Unit = js("alert(message)")

fun createObject(): dynamic = js("({ name: 'John', age: 30 })")

函数式编程特性

高阶函数

// 高阶函数定义
fun calculate(numbers: Array<Int>, operation: (Int) -> Int): Int {
    return numbers.map(operation).sum()
}

// 使用示例
val numbers = arrayOf(1, 2, 3, 4, 5)
val sumOfSquares = calculate(numbers) { it * it }
val sumOfCubes = calculate(numbers) { it * it * it }

Lambda 表达式

// Lambda表达式
val button = document.createElement("button")
button.addEventListener("click", { event ->
    println("Button clicked: ${event.type}")
})

// 简化的Lambda语法
button.addEventListener("click") { event ->
    println("Button clicked: ${event.type}")
}

性能优化技巧

避免不必要的对象创建

// 不好的方式:每次调用都创建新数组
fun getBadNumbers(): Array<Int> {
    return arrayOf(1, 2, 3, 4, 5)
}

// 好的方式:使用全局常量
val GOOD_NUMBERS = arrayOf(1, 2, 3, 4, 5)
fun getGoodNumbers(): Array<Int> = GOOD_NUMBERS

使用内联函数

// 内联函数可以减少函数调用开销
inline fun measureTime(operation: () -> Unit): Long {
    val start = Date().getTime()
    operation()
    val end = Date().getTime()
    return end - start
}

选择合适的数据结构

// 对于频繁查找的场景,使用Map而不是List
val userMap = mapOf(
    "user1" to User("Alice", 25),
    "user2" to User("Bob", 30)
)

// 快速查找
val user = userMap["user1"]

调试和错误处理

类型断言

fun safeCast(value: Any): String? {
    return value as? String
}

fun unsafeCast(value: Any): String {
    return value as String // 如果类型不匹配会抛出异常
}

错误处理

fun safeOperation(): Result<String> {
    return try {
        val result = riskyOperation()
        Result.success(result)
    } catch (e: Exception) {
        Result.failure(e)
    }
}

最佳实践

  1. 充分利用类型安全:尽可能使用具体类型而不是dynamic
  2. 合理使用空安全:避免过度使用!!操作符
  3. 选择合适的集合类型:根据使用场景选择 List、Set 或 Map
  4. 注意性能影响:某些 Kotlin 特性在 JavaScript 中可能有性能开销
  5. 保持代码简洁:利用 Kotlin 的语法糖提高代码可读性

总结

Kotlin/JS 的类型系统为 Web 开发带来了类型安全和现代语言特性的优势。通过理解类型映射、掌握集合操作、合理使用空安全,你可以编写出既安全又高效的 Web 应用程序。

在下一篇文章中,我们将深入探讨 Kotlin/JS 与 JavaScript 的互操作,学习如何在 Kotlin 代码中无缝使用 JavaScript 库和 API。


编辑文章
分享这篇文章:

上一篇
Kotlin/JS 实战项目与最佳实践
下一篇
Kotlin/JS 与 Kotlin Multiplatform 协同开发