Spec-Zone.ru › Kotlin 1.6

Использование кода Kotlin из JavaScript

В зависимости от выбранной системы модулей JavaScript, компилятор Kotlin/JS генерирует различные результаты. Но в целом, компилятор Kotlin генерирует обычные JavaScript-классы, функции и свойства, которые можно свободно использовать из JavaScript-кода. Однако следует помнить о некоторых тонкостях.

Изоляция объявлений в отдельном JavaScript-объекте в простом режиме

Если вы явно установили тип модуля в plain, Kotlin создаёт объект, содержащий все объявления Kotlin из текущего модуля. Это делается для предотвращения загрязнения глобального объекта. Это означает, что для модуля myModule, все объявления доступны для JavaScript через объект myModule. Например:

fun foo() = "Hello"

Вызвать это можно из JavaScript так:

alert(myModule.foo());

Это не применяется, когда вы компилируете свой Kotlin-модуль в JavaScript-модули, такие как UMD (что является стандартным значением для browser и nodejs целей), CommonJS или AMD. В этом случае ваши объявления будут экспортированы в формате, заданном выбранной системой JavaScript-модулей. Например, при использовании UMD или CommonJS, ваш вызов может выглядеть так:

alert(require('myModule').foo());

Дополнительную информацию о системах JavaScript-модулей можно найти в статье о JavaScript-модулях.

Структура пакетов

Kotlin экспортирует свою структуру пакетов в JavaScript, поэтому, если вы не определили свои объявления в корневом пакете, вам нужно использовать полные квалифицированные имена в JavaScript. Например:

package my.qualified.packagename

fun foo() = "Hello"

При использовании UMD или CommonJS, например, ваш вызов может выглядеть так:

alert(require('myModule').my.qualified.packagename.foo())

Или, в случае использования plain в качестве настройки системы модулей:

alert(myModule.my.qualified.packagename.foo());

@JsName аннотация

В некоторых случаях (например, для поддержки перегрузки) компилятор Kotlin изменяет имена сгенерированных функций и атрибутов в JavaScript-коде. Для управления сгенерированными именами можно использовать аннотацию @JsName:

// Module 'kjs'
class Person(val name: String) {
    fun hello() {
        println("Hello $name!")
    }

    @JsName("helloWithGreeting")
    fun hello(greeting: String) {
        println("$greeting $name!")
    }
}

Теперь вы можете использовать этот класс из JavaScript следующим образом:

// If necessary, import 'kjs' according to chosen module system
var person = new kjs.Person("Dmitry");   // refers to module 'kjs'
person.hello();                          // prints "Hello Dmitry!"
person.helloWithGreeting("Servus");      // prints "Servus Dmitry!"

Если бы мы не указали аннотацию @JsName, имя соответствующей функции содержало бы суффикс, рассчитанный по сигнатуре функции, например, hello_61zpoe$.

Обратите внимание, что в некоторых случаях компилятор Kotlin не применяет изменение имён:

  • Объявления external не изменяются.

  • Любые переопределённые функции в не-external классах, наследующих от external классов, не изменяются.

Аргумент @JsName должен быть константной строковой литералом, являющейся допустимым идентификатором. Компилятор выдаст ошибку при попытке передать не-идентификаторную строку в @JsName. Следующий пример вызывает ошибку во время компиляции:

@JsName("new C()")   // error here
external fun newC()

@JsExport аннотация

Аннотация @JsExport в настоящее время отмечена как экспериментальная. Её дизайн может измениться в будущих версиях.

Применяя аннотацию @JsExport к объявлениям верхнего уровня (таким как класс или функция), вы делаете объявление Kotlin доступным из JavaScript. Аннотация экспортирует все вложенные объявления с заданным именем в Kotlin. Она также может быть применена на уровне файла с помощью @file:JsExport.

Для разрешения неоднозначности в экспорте (например, перегрузки функций с одинаковым именем), вы можете использовать аннотацию @JsExport вместе с @JsName для указания имён сгенерированных и экспортированных функций.

Аннотация @JsExport доступна в текущем стандартном компиляторе и в новом компиляторе IR. Если вы используете компилятор IR, вы обязаны использовать аннотацию @JsExport для того, чтобы ваши функции были видимыми из Kotlin в первую очередь.

Для многоплатформенных проектов @JsExport доступна и в общем коде. Она действует только при компиляции для JavaScript и позволяет вам также экспортировать объявления Kotlin, которые не являются специфичными для платформы.

Типы Kotlin в JavaScript

  • Числовые типы Kotlin, за исключением kotlin.Long, сопоставляются с JavaScript Number.

  • kotlin.Char сопоставляется с JavaScript Number, представляющим код символа.

  • Kotlin не может различать числовые типы во время выполнения (за исключением kotlin.Long), поэтому следующий код работает:

    fun f() {
        val x: Int = 23
        val y: Any = x
        println(y as Float)
    }
    
  • Kotlin сохраняет семантику переполнения для kotlin.Int, kotlin.Byte, kotlin.Short, kotlin.Char и kotlin.Long.

  • kotlin.Long не сопоставляется ни с каким JavaScript-объектом, поскольку в JavaScript нет типа 64-битного целого числа. Он эмулируется классом Kotlin.

  • kotlin.String сопоставляется с JavaScript String.

  • kotlin.Any сопоставляется с JavaScript Object (new Object(), {}, и так далее).

  • kotlin.Array сопоставляется с JavaScript Array.

  • Kotlin-коллекции (List, Set, Map, и так далее) не сопоставляются ни с каким конкретным JavaScript-типом.

  • kotlin.Throwable сопоставляется с JavaScript Error.

  • Kotlin сохраняет ленивую инициализацию объектов в JavaScript.

  • Kotlin не реализует ленивую инициализацию свойств верхнего уровня в JavaScript.

Примитивные массивы

Перевод примитивных массивов использует JavaScript TypedArray:

  • kotlin.ByteArray, -.ShortArray, -.IntArray, -.FloatArray, и -.DoubleArray сопоставляются с JavaScript Int8Array, Int16Array, Int32Array, Float32Array, и Float64Array соответственно.

  • kotlin.BooleanArray сопоставляется с JavaScript Int8Array со свойством $type$ == "BooleanArray".

  • kotlin.CharArray сопоставляется с JavaScript UInt16Array со свойством $type$ == "CharArray".

  • kotlin.LongArray сопоставляется с JavaScript Array типа kotlin.Long со свойством $type$ == "LongArray".

Последнее изменение: 07 апреля 2022
Использование зависимостей из npm JavaScript-модули

© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/js-to-kotlin-interop.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API