Spec-Zone.ru › Kotlin 1.8

Использование кода 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 компилятор бэкенд. Если вы используете бэкенд компилятора 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".

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

© 2010–2023 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