提交 b59afada 编写于 作者: W wanganxp

完善json相关文档

上级 2afbebdb
...@@ -245,7 +245,7 @@ uni-app 的自动化测试教程详见:[https://uniapp.dcloud.net.cn/worktile/ ...@@ -245,7 +245,7 @@ uni-app 的自动化测试教程详见:[https://uniapp.dcloud.net.cn/worktile/
除上述文档中声明已经完成的,还有如下需要注意: 除上述文档中声明已经完成的,还有如下需要注意:
- 全端支持:一期只有Android。对于其他平台,开发者可将uvue文件后缀改为vue或nvue,如果没有写Android专有代码,那么也可以使用uni-app js引擎版编译到其他平台,包括iOS App、web及各家小程序。尤其在app-iOS上,由于设备性能本就优秀,所以nvue的方案的性能也足够满足挑剔的开发者。后期官方会提供更完善的 uni-app x的全端支持。 - 全端支持:一期只有Android。虽然uts语言支持swift,可以写原生插件,但iOS版的uvue还未开发完毕。对于iOS或其他小程序、web平台,开发者可将uvue文件后缀改为vue或nvue,如果没有写Android专有代码,那么也可以使用uni-app js引擎版编译到其他平台,包括iOS App、web及各家小程序。尤其在app-iOS上,由于设备性能本就优秀,所以nvue的方案的性能也足够满足挑剔的开发者。后期官方会提供更完善的 uni-app x的全端支持。
- uvue语法:虽然uvue是按vue3实现的,但一期uvue不支持setup,只支持选项式。 - uvue语法:虽然uvue是按vue3实现的,但一期uvue不支持setup,只支持选项式。
- 一期不支持:横屏切换、暗黑模式、自定义转场、多语言、无障碍 - 一期不支持:横屏切换、暗黑模式、自定义转场、多语言、无障碍
- 一期不支持:云开发(已在开发中)、uni-ad。另外包括微信、支付宝、个推等三方sdk封装一期均未启动 - 一期不支持:云开发(已在开发中)、uni-ad。另外包括微信、支付宝、个推等三方sdk封装一期均未启动
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* [控制流程](control.md) * [控制流程](control.md)
* [函数function](function.md) * [函数function](function.md)
* [类型别名type](type-aliases.md) * [类型别名type](type-aliases.md)
* [对象类型object](object.md) <!-- * [对象类型object](object.md) -->
* [类class](class.md) * [类class](class.md)
* [接口interface](interface.md) * [接口interface](interface.md)
* [类型兼容性](type-compatibility.md) * [类型兼容性](type-compatibility.md)
......
...@@ -140,6 +140,14 @@ console.log(map1.get('baz')); ...@@ -140,6 +140,14 @@ console.log(map1.get('baz'));
<!-- UTSJSON.Map.set.compatibility --> <!-- UTSJSON.Map.set.compatibility -->
注意:由于Map的key是唯一的,给同一个key多次set值时,会用新值替换老值。
```ts
const map1: Map<string,string> = new Map(); //定义一个map,key为string类型,value也是string类型
map1.set('key1', "abc");
map1.set('key1', "def");
console.log(map1.get('key1')) //返回 def
```
## 常见操作 ## 常见操作
- 创建map - 创建map
......
...@@ -6,6 +6,19 @@ ...@@ -6,6 +6,19 @@
如果您是js开发者,那么需要一定的学习过程来掌握 UTS 的类型系统。总体原则是你将牺牲一些代码的灵活性,来换取代码的健壮性和高性能。 如果您是js开发者,那么需要一定的学习过程来掌握 UTS 的类型系统。总体原则是你将牺牲一些代码的灵活性,来换取代码的健壮性和高性能。
所谓 类型,即 type,用于对有相同特征的变量或值进行归类。
比如 `"abc"``"你好"`,都属于字符串string,所有string类型有相同的方法、属性,比如`.length`属性获取字符串长度。
UTS 的类型有:
- 基础类型:boolean、number、string、any、null,都是小写,typeof返回类型名称
- 对象类型:Date、Array、Map、Set、USTJSONObject,首字母大写,typeof返回"object",判断准确类型需使用 instanceof
- 使用 type 来自定义类型
- 特殊类型:function、class、error。
- 平台专有类型:Int、Float、Double、NSString、kotlin.Array...,typeof返回"object",判断准确类型需使用 instanceof
<!-- TODO map -->
除了特殊类型,其他类型都可以在变量后面通过`:`加类型名称来给这个变量声明类型。
### 布尔值(boolean) ### 布尔值(boolean)
布尔是简单的基础类型,只有2个值:`true``false` 布尔是简单的基础类型,只有2个值:`true``false`
...@@ -523,26 +536,27 @@ let a3: NSMutableArray = NSMutableArray(array= a) ...@@ -523,26 +536,27 @@ let a3: NSMutableArray = NSMutableArray(array= a)
#### 更多API #### 更多API
Array作为内置对象,还有更多API,[详见](https://uniapp.dcloud.net.cn/uts/buildin-object-api/array.html) Array作为内置对象,还有更多API,[详见](buildin-object-api/array.md)
### JSON@json ### USTJSONObject@ustjsonobject
本章节虽然标题为JSON,但并非 uts 中有一个类型叫`JSON`,本节更多是介绍 uts 中 json 的使用方式,以及介绍内置的 USTJSONObject 对象 json 在 js 中并非一个独立的类型,对一个 json 对象 typeof 返回的是 object
json 在 js 中也并非一个独立的类型,对一个 json 对象 typeof 返回的是 object。 json 在 js 中用起来很自由,但在强类型语言中,不管kotlin、swift、dart...,都没有这么灵活。:
json 在 js 中用起来很自由,但在强类型语言中,不管kotlin、swift、dart...,都没有这么灵活。要求如下:
1. json对象里的每个属性,都需要定义类型 1. json对象里的每个属性,都需要定义类型
2. 每个可为空的属性,都需要加`?.`,才能安全读写 2. 每个可为空的属性,都需要加`?.`,才能安全读写
一般其他强类型语言都要求把json数据转为class、interface或type。 一般其他强类型语言的用法,是把json数据内容,转为class、interface或type。然后就可以`.`了。
在 uts 中使用 JSON,有3种方式:
在 uts 中使用 JSON,有2种方式: 1. 把 json数据转 type,变成一个自定义类型。这不是本章节的内容,详见 [type](type-aliases.md)
2. uts 新增了 UTSJSONObject 对象,可以把 json数据通过字面量赋值 或 JSON.parse()方式,赋值给 uts 内置的 UTSJSONObject 对象。
3. 由于 USTJSONObject有toMap()方法,所以也可以转为Map后使用json数据。
1. 把 json数据 转 type,变成一个类型。有很多转换工具,不管是在线网页还是ide插件。 UTSJSONObject,是一个类型,可以在变量的冒号后面使用,本节的重点就是介绍UTSJSONObject。
2. 使用 uts 内置的 UTSJSONObject 对象,不转type的情况下,尽可能的为开发者提供接近js的灵活性。
#### 对象和数组 #### 对象和数组
...@@ -588,7 +602,7 @@ let jo = [{ ...@@ -588,7 +602,7 @@ let jo = [{
#### 定义 UTSJSONObject #### 定义 UTSJSONObject
可以通过 object 字面量的方式定义一个 UTSJSONObject 对象,编译器会根据字面量自动推导类型。 可以通过对象字面量的方式定义一个 UTSJSONObject 对象,编译器会根据字面量自动推导类型。
```ts ```ts
let jo = { let jo = {
...@@ -602,8 +616,6 @@ let jo2 = { ...@@ -602,8 +616,6 @@ let jo2 = {
} }
``` ```
严谨的JSON,x和y属性是需要两侧加引号包围的。对象字面量的属性名可以不加引号,当包含特殊字符时建议开发者加上引号。
如果属性名包括`-`,则必须两侧加引号包围。尽管在 kotlin 中属性名称包含`$``_`等也需要转义,但是 UTS 中是无需特殊处理的,编译器会自动转换。 如果属性名包括`-`,则必须两侧加引号包围。尽管在 kotlin 中属性名称包含`$``_`等也需要转义,但是 UTS 中是无需特殊处理的,编译器会自动转换。
对于纯字面量,jo 后面的 `:UTSJSONObject` 可以省略,这些类型比较简单,可以自动推导类型。包括下面的多层嵌套,类型也不会推导出错。 对于纯字面量,jo 后面的 `:UTSJSONObject` 可以省略,这些类型比较简单,可以自动推导类型。包括下面的多层嵌套,类型也不会推导出错。
...@@ -619,46 +631,19 @@ let rect = { ...@@ -619,46 +631,19 @@ let rect = {
} }
console.log(rect) console.log(rect)
``` ```
<!--
对于复杂的json,通常会给它配套定义一个type,来描述这个json的内部数据类型。
此时需要使用`type`关键字,它的作用就是定义类型,在很多场景都可以使用。
```ts
type personType = {
id : number,
name : string
}
let a1=1,a2=2,b1="张三",b2="李四"
let personList [] : UTSJSONObject[]
personList = [
{ "id": a1, "name": b1 },
{ "id": a2, "name": b2 },
] as personType[]
```
很多json对象在构造时,是没有具体数据的。
```ts
let jo = {}
jo = JSON.parse({"result":true, "count":42})
```
-->
有关字面量定义 UTSJSONObject 对象的信息,[详见](literal.md#object) 也就是对于形如`{x:samething}`的对象字面量,如果赋值时不指定类型,在 uts 中会被自动推导为 UTSJSONObject。如果你需要转 type,则需显式声明。
除了字面量定义对象,经常用到的是通过 `JSON.parse()`,把一个 JSON 字符串转成对象。 除了字面量定义UTSJSONObject对象,经常用到的是通过 `JSON.parse()`,把一个 JSON 字符串转成UTSJSONObject对象。
uts 内置了大写的 `JSON` 对象,有parse()、stringify()等方法。注意这和 UTSJSONObject 不是一个对象。大写 `JSON` 内置对象,web端也是存在的。而 UTSJSONObject 是 uts 新增的。 uts 内置了大写的 `JSON` 对象,有parse()、stringify()等方法。注意`JSON``UTSJSONObject`不是一个对象。大写 `JSON` 内置对象,web端也是存在的。而 UTSJSONObject 是 uts 新增的。
```ts ```ts
let s = `{"result":true, "count":42}` // 常见场景中,这个字符串更多来自于网络或其他应用传输。 let s = `{"result":true, "count":42}` // 常见场景中,这个字符串更多来自于网络或其他应用传输。
let jo = JSON.parse(s) // 这个代码适用于HBuilderX 3.9以前 let jo = JSON.parse(s) // 这个代码适用于HBuilderX 3.9以前
``` ```
在 HBuilderX 3.9以前,`JSON.parse()`返回的`UTSJSONObject`。但因为有时网络或其他应用传入的 JSON 数据根节点是数组,而不是对象,会导致崩溃。 在 HBuilderX 3.9以前,`JSON.parse()`返回的`UTSJSONObject`。但因为有时网络或其他应用传入的 JSON 数据根节点是数组,而不是对象,会导致崩溃。
所以从 HBuilderX 3.9起,`JSON.parse()`返回的类型改为`any`,即可能返回对象、也可能返回数组。这样就需要开发者自行再`as`一下来指定具体类型了。 所以从 HBuilderX 3.9起,`JSON.parse()`返回的类型改为`any`,即可能返回对象、也可能返回数组。这样就需要开发者自行再`as`一下来指定具体类型了。
...@@ -682,7 +667,13 @@ let jr = JSON.parseArray(s) ...@@ -682,7 +667,13 @@ let jr = JSON.parseArray(s)
全局对象JSON,除了parse()、parseObject()、parseArray()外,还有stringify()来把json转为字符串。[详见](buildin-object-api/json.md) 全局对象JSON,除了parse()、parseObject()、parseArray()外,还有stringify()来把json转为字符串。[详见](buildin-object-api/json.md)
#### 访问 UTSJSONObject 中的属性 #### 验证类型
```ts
console.log(typeof jo); //返回 object
console.log(jo instanceof UTSJSONObject); //返回 true
```
#### 访问 UTSJSONObject 中的属性数据
```ts ```ts
let rect = { let rect = {
...@@ -701,8 +692,8 @@ let rect = { ...@@ -701,8 +692,8 @@ let rect = {
`rect.x``rect.size.width` `rect.x``rect.size.width`
这种写法比较简单,和js习惯一致,但在 UTS 中限制较多。它的使用有如下前提: 这种写法比较简单,和js习惯一致,但在 UTS 中限制较多。它的使用有如下前提:
- 通过type声明了对象的数据结构,也就是需要单独定义一个type,转为type后再使用。详见type章节。这也是大多数强类型语言使用json的方式 - 仅限于web和Android,在iOS上swift不支持`.`操作符
- 如未定义type,则仅限于web和Android,在iOS上swift不支持`.`操作符。在Android上也只支持字面量定义json(因为类型可推导)。如果是`JSON.parse()`转换的,则不能使用。 - 在Android上也只支持字面量定义json(因为类型可推导)。如果是`JSON.parse()`转换的,则不能使用。
2. [""]下标属性 2. [""]下标属性
`rect["x"]` `rect["x"]`
...@@ -728,10 +719,10 @@ let rect = { ...@@ -728,10 +719,10 @@ let rect = {
} }
console.log(rect.x) //20 但iOS无法使用.操作符 console.log(rect.x) //20 但iOS无法使用.操作符
console.log(rect["x"]) //20 console.log(rect["x"]) //20 但类型其实未知,如果继续操作则需要as
console.log(rect.size.width) //80 但iOS无法使用.操作符 console.log(rect.size.width) //80 但iOS无法使用.操作符
console.log((rect["size"] as UTSJSONObject)["width"]) //80 console.log((rect["size"] as UTSJSONObject)["width"]) //80 使用as后需要整体用()括起来再继续使用下标[]
// 如果存在嵌套,那么需要先把第一层转成 UTSJSONObject 或数组,之后再用下标访问下一层 // 如果存在嵌套,那么需要先把第一层转成 UTSJSONObject 或数组,之后再用下标访问下一层
...@@ -741,7 +732,7 @@ console.log((rect["border"] as UTSJSONObject[])[0]["color"]); // red ...@@ -741,7 +732,7 @@ console.log((rect["border"] as UTSJSONObject[])[0]["color"]); // red
``` ```
如果是 `JSON.parse` 解析的数组,目前只能通过下标访问。 如果是 `JSON.parse` 解析的数组,目前只能通过下标访问,无法使用`.`操作符
```ts ```ts
let listData = JSON.parse(`{"result":true, "count":42}`) as UTSJSONObject let listData = JSON.parse(`{"result":true, "count":42}`) as UTSJSONObject
...@@ -760,7 +751,11 @@ console.log((j['test'] as UTSJSONObject)['a-b']); ...@@ -760,7 +751,11 @@ console.log((j['test'] as UTSJSONObject)['a-b']);
3. 通过 keyPath 访问 UTSJSONObject 数据 3. 通过 keyPath 访问 UTSJSONObject 数据
`HBuilderX` 3.9.0 之后的版本,UTSJSONObject 提供了另外一种属性访问方式,keypath。如果你了解 XPath、JSONPath 的话,这个概念类似。 `HBuilderX` 3.9.0 之后的版本,UTSJSONObject 提供了另外一种属性访问方式,keyPath。如果你了解 XPath、JSONPath 的话,这个概念类似。
kyepath是把`.`操作符作为一个字符串传入了UTSJSONObject的一个方法中,比如`utsObj.getString("address.detailInfo.street")`
相对于受限制`.`和需要经常as的下标,更推荐使用keyPath方式来操作UTSJSONObject。
以下面的 UTSJSONObject 为例 以下面的 UTSJSONObject 为例
```ts ```ts
...@@ -827,13 +822,66 @@ let detailInfoObj = utsObj["detailInfo"] as UTSJSONObject ...@@ -827,13 +822,66 @@ let detailInfoObj = utsObj["detailInfo"] as UTSJSONObject
let street = utsObj["street"] as String let street = utsObj["street"] as String
``` ```
上面的写法,啰嗦且容易出错。因此,我们提供了更易用的 keypath 写法,帮助开发者摆脱复杂的对象嵌套关系: 上面的写法,啰嗦且容易出错。因此,我们提供了更易用的 keyPath 写法,帮助开发者摆脱复杂的对象嵌套关系:
```ts ```ts
// 结果:the wall street // 结果:the wall street
let street = utsObj.getString("address.detailInfo.street") let street = utsObj.getString("address.detailInfo.street")
``` ```
当然,除了直接使用UTSJSONObject外,在 uts 中使用json数据还有2种方式:
1. UTSJSONObject.toMap() 转为Map对象 [见下](#Map)
2. 把json字符串或对象字面量通过type转为自定义类型,这是ts里经常使用的方式 [详见](type-aliases.md)
#### 更多API
UTSJSONObject对象还有很多API,[详见](buildin-object-api/utsjsonobject.md)
### Map
Map 是一种 key value 形式的数据类型。
与二维数组相比,Map的key不能重复,并且读写的方式是get()、set()。与UTSJSONObject相比,Map的性能更高,但对数据格式有要求。
#### 定义
```ts
//定义一个map1,key为string类型,value也是string类型
const map1: Map<string,string> = new Map();
map1.set('key1', "abc");
console.log(map1.get('key1') //返回 abc
//定义一个map1,key为number类型,value是Map类型
const map2: Map<number,Map<string,string>> = new Map();
map2.set(1, map1); //把map1作为value传进来
console.log(map2.get(1)); //返回map1
console.log(map2.get(1)?.get("key1")); //返回 abc。因为名为1的key不一定存在,map2.get(1)可能为null,此时需使用 ?. 才能链式调用
```
注意在HBuilderX中console.log一个Map时,返回内容格式如下:
[Object] Map(3) {"sex":0,"name":"zhangsan","age":12} at pages/index/index.uvue:60
开头的[Object]代表其typeof的类型,Map代表它的实际类型,(3)是map的size,{...} 是Map的内容。
还可以把一个UTSJSONObject转为Map
```ts
let userA = {
name: "zhangsan",
age: 12,
sex: 0
} // userA 被推导为UTSJSONObject
let userMap = userA.toMap() //UTSJSONObject有toMap方法
```
#### 验证类型
```ts
console.log(typeof map1); //返回 object
console.log(map1 instanceof Map); //返回 true
```
#### 更多API
Map对象还有很多API,delete、clear等,[详见](buildin-object-api/map.md)
### any类型 @any ### any类型 @any
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
接口提供了一种约定,用于确保对象的属性和方法遵循特定的模式。接口只能包含抽象的声明,不能包含具体的实现。接口本身不能被实例化,它可以被类所采用,以提供具体的实现。 接口提供了一种约定,用于确保对象的属性和方法遵循特定的模式。接口只能包含抽象的声明,不能包含具体的实现。接口本身不能被实例化,它可以被类所采用,以提供具体的实现。
在 ts 中,经常把json数据转为 interface 或 type 。但在 uts 中,只适合转 type,不适合使用 interface。因为 interface 在 kotlin 和 swift 中另有不同。
<!-- TODO 这里需要补充和ts的interface的区别,编译到原生时都变成了什么 -->
接口使用关键字 `interface` 声明。 接口使用关键字 `interface` 声明。
```ts ```ts
......
...@@ -92,7 +92,7 @@ Boolean字面量的自动类型推导简单而统一,全平台必然被自动 ...@@ -92,7 +92,7 @@ Boolean字面量的自动类型推导简单而统一,全平台必然被自动
数字字面量的类型推导,[详见](data-type.md#@autotypefornumber) 数字字面量的类型推导,[详见](data-type.md#@autotypefornumber)
### 字符串字面量 @object ### 字符串字面量@string
字符串字面量是由双引号(")对或单引号(')括起来的零个或多个字符。字符串被限定在同种引号之间;也即,必须是成对单引号或成对双引号。下面的例子都是字符串字面值: 字符串字面量是由双引号(")对或单引号(')括起来的零个或多个字符。字符串被限定在同种引号之间;也即,必须是成对单引号或成对双引号。下面的例子都是字符串字面值:
...@@ -158,40 +158,39 @@ const coffees = ["French Roast", "Colombian", "Kona"] ...@@ -158,40 +158,39 @@ const coffees = ["French Roast", "Colombian", "Kona"]
### 对象字面量@object-literal ### 对象字面量@object-literal
在JS中,对象字面值是封闭在花括号对({})中的一个对象的零个或多个“属性名—值”对的(元素)列表。 在JS中,对象字面值是封闭在花括号对`{}`中的一个对象的零个或多个“属性名—值”对的(元素)列表。
在uts中,对象字面量赋值给变量,默认会被推导为[UTSJSONObject](data-type.md#USTJSONObject)类型。
#### 如何创建一个对象字面量 ```ts
1 我们在kotlin/swift 语言中使用 [UTSJSONObject](./buildin-object-api/utsjsonobject.md) 作为载体实现了JS的这个规范,开发者可以正常使用字面量创建此对象
```js
// 创建对象 // 创建对象
let userA = { let userA = {
name: "zhangsan", name: "zhangsan",
age: 12 age: 12
} }
console.log(user) console.log(userA)
``` ```
2 除了字面意思:字面量赋值之外,对象字面量还有一个来源是`JSON.parse("xxx")` 将字符串转换为对象 对上述的userA进行typeof,得到的是object。进行 instanceof UTSJSONObject,得到的是true。也就是等同于:
```js ```ts
let arrayObj = JSON.parse('["a","b","c"]') // 创建对象
console.log(arrayObj) let userA:UTSJSONObject = {
name: "zhangsan",
age: 12
}
console.log(userA)
``` ```
这里要介绍一个比较有用的做法,比如我有一个类型对象,可以通过`JSON.stringify`得到序列化后的字符串,再通过`JSON.parse("xxx")`的方式,将其转换为对象 注意花括号还有一个使用场景,被用于type时,是定义了一个自定义类型。下面的代码通过type关键字定义了一个 User类型,该自定义类型有2个属性,string类型的name和number类型的age。
```ts ```ts
type User{ type User{
name:string = "" name:string = ""
age:number = 0 age:number = 0
} }
let jsonObject = JSON.parse(JSON.stringify(new User()))
``` ```
<!--
#### 如何使用对象字面量 #### 如何使用对象字面量
在传统JS中,对象字面量的返回结果就是一个通用的object. 但是在 kotlin / swift 它是一个 支持下标访问,成员迭代等特性的看上去像是一个`object``UTSJSONObject`实现。 在传统JS中,对象字面量的返回结果就是一个通用的object. 但是在 kotlin / swift 它是一个 支持下标访问,成员迭代等特性的看上去像是一个`object``UTSJSONObject`实现。
...@@ -220,7 +219,7 @@ userMap.forEach(function(key:string,value:any){ ...@@ -220,7 +219,7 @@ userMap.forEach(function(key:string,value:any){
console.log(value) console.log(value)
}) })
``` ```
-->
### RegExp字面量 ### RegExp字面量
正则表达式是字符被斜线围成的表达式。下面是一个正则表达式文字的一个例子。 正则表达式是字符被斜线围成的表达式。下面是一个正则表达式文字的一个例子。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册