title | date | author | tags | keywords | categories | reward | reward_title | reward_wechat | reward_alipay | source_url |
---|---|---|---|---|---|---|---|---|---|---|
[译]JavaScript Interop |
2014-12-24 01:57:00 -0800 |
Hadi Hariri |
官方动态 |
false |
Have a nice Kotlin! |
当使用JavaScript,即创建一个可编译为JavaScript的Kotlin应用程序时,我们经常需要与JavaScript中的现有库进行互操作。虽然Kotlin已经为此提供了支持,但我们在M10中添加了更多的选项,使互操作性更加容易 </ span>
在M10中,我们添加了动态</ strong>关键字 [1] </ strong>,这样我们可以将类型声明为动态的,允许某些互操作性以前可能更麻烦。例如,当使用jQuery,直到M10,我们唯一的选择是使用Kotlin提供的强类库。至于M10,我们现在也可以使用动态关键字
{% raw %}
{% endraw %}jquery.getJSON(KotlinCommitsURL) { commits ->
val commitsTable = jquery("#kotlin-commits")
commits.forEach { commit ->
commitsTable.append("""
<tr>
<td><a href=${commit.html_url}>${commit.sha.substring(0, 6)}</a></td>
<td>${commit.commit.message}</td>
</tr>""")
}
}
{% raw %}
{% endraw %}上述代码调用 jQuery </ em>上的 getJSON </ em>函数返回GitHub提交的列表。该函数使用带有单个参数的lambda,即实际的提交。此列表中的每个条目依次是提交条目,其中包含自己的字段,例如 html_url </ em>或 commit.message </ em>。 在代码 jQuery中,提交</ em>和提交</ em>都是动态的,这意味着我们调用这些的任何东西都将在运行时被解析,即JavaScript解释器。这允许两件事情:
- 不必使用强类型的库来处理jQuery
- 能够消耗以前未定义的模型
第二个功能是非常有用的,因为这意味着我们不必创建中间强类型的类来消耗HTTP端点。 当然,我们甚至可以使用诸如 </ em>循环的语言结构来做同样的事情,不仅使用 forEach </ em>扩展功能。
{% raw %}
{% endraw %}jquery.getJSON(KotlinCommitsURL) { commits ->
val commitsTable = jquery("#kotlin-commits")
for(commit in commits) {
commitsTable.append("""
<tr>
<td><a href=${commit.html_url}>${commit.sha.substring(0, 6)}</a></td>
<td>${commit.commit.message}</td>
</tr>""")
}
}
{% raw %}
{% endraw %}为了使此代码工作,我们仍然需要将jQuery </ em>声明为动态的,并将其与Kotlin的相应本机等价物进行标记
{% raw %}
{% endraw %}native("$")
val jquery : dynamic = noImpl
{% raw %}
{% endraw %}需要 noImpl </ em>,因为Kotlin中的不可为空的变量需要初始化,在这种情况下会引发异常,但是这并不会发生,因为它被有效地编译成JavaScript并在客户机上调用 - 侧。已经存在于M10之前的本机</ em>注释告诉Kotlin JavaScript中的标识符相当于什么。
当声明动态类型时,某些操作符在JavaScript中本地运行,例如索引访问器:
{% raw %}
{% endraw %}elements: dynamic
// in Kotlin
elements[1]
{% raw %}
{% endraw %}将编译为:
{% raw %}
{% endraw %}elements[i]
{% raw %}
{% endraw %}在JavaScript中。
在M10中添加的另一个功能是可以在Kotlin代码中嵌入一些本机JavaScript代码。我们可以使用 js </ em>函数:
{% raw %}
{% endraw %} jquery.getJSON(KotlinCommitsURL) { commits ->
js("console.log('Calling JavaScript')")
val commitsTable = jquery("#kotlin-commits")
{% raw %}
{% endraw %}第二行在由编译产生的输出中插入</ u> console.log('Calling JavaScript')</ em>,将JavaScript与Kotlin代码相结合。
M10还在IntelliJ IDEA for Kotlin中添加了语言注入支持。虽然这适用于任何字符串和任何语言,而不仅仅是JavaScript,但是当使用 js </ em>时,它肯定是有用的,允许这样做:
{% raw %}
{% endraw %}看起来像这样:
{% raw %}
{% endraw %}注入JavaScript语言时:
{% raw %}
{% endraw %}除了动态</ em>和 js </ em>之外,我们还引入了对JavaScript的nativeGetter,nativeSetter </ em>和 nativeInvoke </ em>注释的支持,我们已经覆盖了 M10发布帖子 。
这些新功能都提供了与JavaScript的更好的互操作性,但是他们并没有争取继续为JavaScript中的现有库和框架提供强类型的支持。
[1] </ strong>
“动态”是一个软关键字:
- 如果它发生在非类型上下文中,则它是一个标识符
- 在类型上下文中,当后面跟着一个点(除了将接收器类型与函数/属性名称分开的点除外)或一个尖括号<,它是一个标识符
- 在左侧的::在一个可调参考中:dynamic :: foo意味着动态有一个正常的标识符