Skip to content

Commit 4010fc5

Browse files
committed
build(Project): update version to v0.1.1-SNAPSHOT
1 parent 90c13f1 commit 4010fc5

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

changelog.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,84 @@
4949
### Breaking Changes
5050
5151

52+
## v0.1.1-SNAPSHOT(2021/8/14)
53+
### Bug Fixes
54+
- 解决了一个潜在的类型转换异常:
55+
56+
> 说明:由于Array中某些方法(例如find()、findIndex()等)方法会遍历数组中的所有值,包括undefined, 而在从js到java的类型映射中,
57+
> WebEngine内在的类型映射机制会将Js中的undefined值映射成Java中一个值为"undefined"的字符串。
58+
>
59+
> 这样就带来一个问题,如果我们完全依赖内在的类型映射机制,那么就意味着我们在java层面无法分辨一个来自js的值为"undefined"实际到底指代的是什么,换言之,这就造成了潜在的歧义性。
60+
> 这种歧义性的消除当然可以依赖我们与js代码之间的约定,比如可以规定,在js代码中不允许将一个undefined值传递到java中,然而这种约定很难是强制性的,它很可能由于编码上的不谨慎
61+
> 从而在某个意想不到的的场合被打破。
62+
>
63+
> 除了歧义性,一个更加实际的问题在于,一个代表undefined的字符串很可能会被当初其他类型的值作为函数参数进行传递,这时就有可能引发类型错误,考虑以下情形。
64+
> 假设在js中我们有这样一个数组**var raw = [0, 1, 2, 3, null, undefined, 6]**,现在我们需要在java中遍历它,依次对其中的值进行一些计算,那么可以使用如下方法:
65+
>
66+
>>val raw = webEngine.executeScript("raw")
67+
>>
68+
>>val jsArray = JsArray.intArrayOf(raw)
69+
>>
70+
>>jsArray.forEach { index, value ->
71+
>>
72+
>> if(value != null) doSomeCalculationWith(value) // 对每一个元素做一些计算工作
73+
>>
74+
>> }
75+
>
76+
> 在上面这个例子中,value参数的类型为Int?,在处理raw数组的前五个元素时,一切都进行的很顺利,因为这些元素或者是整数或者是null;然而,当处理到第六个元素时,异常就发生了。第六个元素的值为undefined,在java中,WebEngine的类型映射机制
77+
> 会将其映射为一个“undefined”字符串,而value参数要求一个Int?值,因此系统会尝试将“undefined”字符串强制转换为Int?,这种类型转换当然是要失败的,因此最终的结果就是引发了一个类型转换异常。
78+
>
79+
> 要解决这个问题实际上并不困难,不难看出,这个问题的根源在于js与java的类型系统的不兼容性——二者的类型并非一一对应的,具体而言,java中没有一个在语义上与js undefined严格对应的值或者类型,WebEngine的解决方案是将undefined转换为对应的字符串,这显然是一种折衷的做法。
80+
> 而在实际中,undefined的语义常常与null解决(尤其是当我们从java的视角来考虑问题时),因此,一个同样折衷的做法是,在js层面将可能传递到java的undefined的值预先就转换为null。
81+
> 在实际的代码中,我们定义了一个undefined2Null()函数来生成相关的代码片段。
82+
83+
### Feature
84+
- 增加了以下静态接口,更加方便使用
85+
- JsArrayInterface<T>.isJsArray(obj: Any)
86+
- JsArray<T>.newJsStringArray(env: JSObject, initialSize: Int = 0)
87+
- JsArray<T>.newJsIntArray(env: JSObject, initialSize: Int = 0)
88+
- JsArray<T>.newJsDoubleArray(env: JSObject, initialSize: Int = 0)
89+
- JsArray<T>.newBooleanArray(env: JSObject, initialSize: Int = 0)
90+
- JsArray<T>.newJSObjectArray(env: JSObject, initialSize: Int = 0)
91+
- JsArray<T>.newJSObjectArray(env: JSObject, initialSize: Int = 0)
92+
- JsArray<T>.newJsAnyArray(env: JSObject, initialSize: Int = 0)
93+
94+
95+
- 为JsArray中迭代相关的接口添加了扩展API,现在我们可以使用kotlin为lambda函数提供语法糖来写回调函数,而无需创建匿名对象了,包括:
96+
- JsArray<T>.find()
97+
- JsArray<T>.findIndex()
98+
- JsArray<T>.forLoop()
99+
- JsArray<T>.forEach()
100+
- JsArray<T>.filter()
101+
- JsArray<T>.map()
102+
- JsArray<T>.every()
103+
- JsArray<T>.some()
104+
- JsArray<T>.reduce()
105+
- JsArray<T>.reduceRight()
106+
- JsArray<T>.sort()
107+
```kotlin
108+
// 使用匿名对象的方式:
109+
jsArray.forEach(object : TypedIteratorCallback<Int?, Unit> {
110+
override fun call(currentValue: Int?, index: Int, total: Int?, arr: Any?) {
111+
println("jsArray[$index]=$currentValue")
112+
}
113+
})
114+
115+
// 现在可以这样简写了
116+
jsArray.forEach{ index, value->
117+
println("jsArray[$index]=$currentValue")
118+
}
119+
```
120+
- 重载了reduce()和reduceRight(),现在可以设定初始值了:
121+
- JSArray<T>.reduce(initialValue: T?, callback: ...)
122+
- JSArray<T>.reduceRight(initialValue: T?, callback: ...)
123+
124+
### Breaking Changes
125+
- 更改了JsArrayIteratorCallback接口中call函数的签名,将其total参数的类型由R?转变为T?
126+
- 更改了TypedCallback3接口中的函数签名,同样将total参数的类型由R?转变为T?
127+
- 去除了reduce()与reduceRight()函数类型参数R,现在这两个函数的返回值类型将与数组类型一致(即为T?)
128+
- 更改了由js到java的类型映射逻辑,统一将传递给java的undefined值转换为null
129+
- 由于java中没有undefined的等价物,因此对于一些函数,undefined和null被认为具有相同的逻辑含义,比如:
130+
- (java) include(null) <=> (js) includes(null) && indexOf(null) || includes(undefined)
131+
- (java) indexOf(null) <=> (js) {let __tmp=indexOf(null);__tmp!=-1? __tmp : indexOf(undefined)}
132+
- (java) lastIndexOf(null) <=> (js) {let __tmp=lastIndexOf(null);__tmp!=-1? __tmp : lastIndexOf(undefined)}

0 commit comments

Comments
 (0)