提交 b59afada 编写于 作者: W wanganxp

完善json相关文档

上级 2afbebdb
......@@ -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,只支持选项式。
- 一期不支持:横屏切换、暗黑模式、自定义转场、多语言、无障碍
- 一期不支持:云开发(已在开发中)、uni-ad。另外包括微信、支付宝、个推等三方sdk封装一期均未启动
......
......@@ -5,7 +5,7 @@
* [控制流程](control.md)
* [函数function](function.md)
* [类型别名type](type-aliases.md)
* [对象类型object](object.md)
<!-- * [对象类型object](object.md) -->
* [类class](class.md)
* [接口interface](interface.md)
* [类型兼容性](type-compatibility.md)
......
......@@ -140,6 +140,14 @@ console.log(map1.get('baz'));
<!-- 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
......
......@@ -6,6 +6,19 @@
如果您是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)
布尔是简单的基础类型,只有2个值:`true``false`
......@@ -523,26 +536,27 @@ let a3: NSMutableArray = NSMutableArray(array= a)
#### 更多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对象里的每个属性,都需要定义类型
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插件。
2. 使用 uts 内置的 UTSJSONObject 对象,不转type的情况下,尽可能的为开发者提供接近js的灵活性。
UTSJSONObject,是一个类型,可以在变量的冒号后面使用,本节的重点就是介绍UTSJSONObject。
#### 对象和数组
......@@ -588,7 +602,7 @@ let jo = [{
#### 定义 UTSJSONObject
可以通过 object 字面量的方式定义一个 UTSJSONObject 对象,编译器会根据字面量自动推导类型。
可以通过对象字面量的方式定义一个 UTSJSONObject 对象,编译器会根据字面量自动推导类型。
```ts
let jo = {
......@@ -602,8 +616,6 @@ let jo2 = {
}
```
严谨的JSON,x和y属性是需要两侧加引号包围的。对象字面量的属性名可以不加引号,当包含特殊字符时建议开发者加上引号。
如果属性名包括`-`,则必须两侧加引号包围。尽管在 kotlin 中属性名称包含`$``_`等也需要转义,但是 UTS 中是无需特殊处理的,编译器会自动转换。
对于纯字面量,jo 后面的 `:UTSJSONObject` 可以省略,这些类型比较简单,可以自动推导类型。包括下面的多层嵌套,类型也不会推导出错。
......@@ -619,46 +631,19 @@ let 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
let s = `{"result":true, "count":42}` // 常见场景中,这个字符串更多来自于网络或其他应用传输。
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`一下来指定具体类型了。
......@@ -682,7 +667,13 @@ let jr = JSON.parseArray(s)
全局对象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
let rect = {
......@@ -701,8 +692,8 @@ let rect = {
`rect.x``rect.size.width`
这种写法比较简单,和js习惯一致,但在 UTS 中限制较多。它的使用有如下前提:
- 通过type声明了对象的数据结构,也就是需要单独定义一个type,转为type后再使用。详见type章节。这也是大多数强类型语言使用json的方式
- 如未定义type,则仅限于web和Android,在iOS上swift不支持`.`操作符。在Android上也只支持字面量定义json(因为类型可推导)。如果是`JSON.parse()`转换的,则不能使用。
- 仅限于web和Android,在iOS上swift不支持`.`操作符
- 在Android上也只支持字面量定义json(因为类型可推导)。如果是`JSON.parse()`转换的,则不能使用。
2. [""]下标属性
`rect["x"]`
......@@ -728,10 +719,10 @@ let rect = {
}
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"] as UTSJSONObject)["width"]) //80
console.log((rect["size"] as UTSJSONObject)["width"]) //80 使用as后需要整体用()括起来再继续使用下标[]
// 如果存在嵌套,那么需要先把第一层转成 UTSJSONObject 或数组,之后再用下标访问下一层
......@@ -741,7 +732,7 @@ console.log((rect["border"] as UTSJSONObject[])[0]["color"]); // red
```
如果是 `JSON.parse` 解析的数组,目前只能通过下标访问。
如果是 `JSON.parse` 解析的数组,目前只能通过下标访问,无法使用`.`操作符
```ts
let listData = JSON.parse(`{"result":true, "count":42}`) as UTSJSONObject
......@@ -760,7 +751,11 @@ console.log((j['test'] as UTSJSONObject)['a-b']);
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 为例
```ts
......@@ -827,13 +822,66 @@ let detailInfoObj = utsObj["detailInfo"] as UTSJSONObject
let street = utsObj["street"] as String
```
上面的写法,啰嗦且容易出错。因此,我们提供了更易用的 keypath 写法,帮助开发者摆脱复杂的对象嵌套关系:
上面的写法,啰嗦且容易出错。因此,我们提供了更易用的 keyPath 写法,帮助开发者摆脱复杂的对象嵌套关系:
```ts
// 结果:the wall 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
......
......@@ -2,6 +2,10 @@
接口提供了一种约定,用于确保对象的属性和方法遵循特定的模式。接口只能包含抽象的声明,不能包含具体的实现。接口本身不能被实例化,它可以被类所采用,以提供具体的实现。
在 ts 中,经常把json数据转为 interface 或 type 。但在 uts 中,只适合转 type,不适合使用 interface。因为 interface 在 kotlin 和 swift 中另有不同。
<!-- TODO 这里需要补充和ts的interface的区别,编译到原生时都变成了什么 -->
接口使用关键字 `interface` 声明。
```ts
......
......@@ -92,7 +92,7 @@ Boolean字面量的自动类型推导简单而统一,全平台必然被自动
数字字面量的类型推导,[详见](data-type.md#@autotypefornumber)
### 字符串字面量 @object
### 字符串字面量@string
字符串字面量是由双引号(")对或单引号(')括起来的零个或多个字符。字符串被限定在同种引号之间;也即,必须是成对单引号或成对双引号。下面的例子都是字符串字面值:
......@@ -158,40 +158,39 @@ const coffees = ["French Roast", "Colombian", "Kona"]
### 对象字面量@object-literal
在JS中,对象字面值是封闭在花括号对({})中的一个对象的零个或多个“属性名—值”对的(元素)列表。
在JS中,对象字面值是封闭在花括号对`{}`中的一个对象的零个或多个“属性名—值”对的(元素)列表。
在uts中,对象字面量赋值给变量,默认会被推导为[UTSJSONObject](data-type.md#USTJSONObject)类型。
#### 如何创建一个对象字面量
1 我们在kotlin/swift 语言中使用 [UTSJSONObject](./buildin-object-api/utsjsonobject.md) 作为载体实现了JS的这个规范,开发者可以正常使用字面量创建此对象
```js
```ts
// 创建对象
let userA = {
name: "zhangsan",
age: 12
}
console.log(user)
console.log(userA)
```
2 除了字面意思:字面量赋值之外,对象字面量还有一个来源是`JSON.parse("xxx")` 将字符串转换为对象
对上述的userA进行typeof,得到的是object。进行 instanceof UTSJSONObject,得到的是true。也就是等同于:
```js
let arrayObj = JSON.parse('["a","b","c"]')
console.log(arrayObj)
```ts
// 创建对象
let userA:UTSJSONObject = {
name: "zhangsan",
age: 12
}
console.log(userA)
```
这里要介绍一个比较有用的做法,比如我有一个类型对象,可以通过`JSON.stringify`得到序列化后的字符串,再通过`JSON.parse("xxx")`的方式,将其转换为对象
注意花括号还有一个使用场景,被用于type时,是定义了一个自定义类型。下面的代码通过type关键字定义了一个 User类型,该自定义类型有2个属性,string类型的name和number类型的age。
```ts
type User{
name:string = ""
age:number = 0
}
let jsonObject = JSON.parse(JSON.stringify(new User()))
```
<!--
#### 如何使用对象字面量
在传统JS中,对象字面量的返回结果就是一个通用的object. 但是在 kotlin / swift 它是一个 支持下标访问,成员迭代等特性的看上去像是一个`object``UTSJSONObject`实现。
......@@ -220,7 +219,7 @@ userMap.forEach(function(key:string,value:any){
console.log(value)
})
```
-->
### RegExp字面量
正则表达式是字符被斜线围成的表达式。下面是一个正则表达式文字的一个例子。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册