uts语法快速掌握笔记

1,538 阅读12分钟

前言:

本篇文章仅记录uts语法的特别、区别之处,如果你对TypeScript语言足够了解,这篇文章可以让你快速掌握uts

本篇文章引用uni-app官网对于UTS语法的介绍,详情请查看 uniapp.dcloud.net.cn/tutorial/sy…

UTS介绍

uts是一门跨平台的,高性能的,强类型的现代编程语言 它可以被编译成不同类型的语言:

  1. web平台,可被编译成javascript
  2. andord平台,可被编译成Kotlin
  3. iOS平台,编译Swift 可以用条件编译调用不同平台特有的扩展语法

基本语法

变量类型

声明一个可重新赋值的变量。语法 `let [变量名] : [类型] = 值;`。

> 相当于 TypeScript 中的 let,kotlin 中的 var

常量类型

声明一个只读常量,只能为其赋值一次。语法 `const [变量名] : [类型] = 值;`。

> 相当于 TypeScript 中的 const, kotlin 中的 val

变量命名规则

  • 变量名称可以包含数字和字母。
  • 除了下划线 _ 外,不能包含其他特殊字符,包括空格。
  • 变量名不能以数字开头。

注意:与 TypeScript 不同的是,uts 不允许以 $ 开头命名变量

类型自动推导

uts具备类型自动推导。在定义变量时如果直接赋值,而不使用冒号定义类型,也可以合法运行。

条件(三元)运算符

数据类型

数字(Number)

在 kotlin 和 swift 中,数字还有其他分支类型,包括Int、Float、Double。有些系统API或三方SDK的传入和返回强制约定了这些分支类型,此时无法使用 number。 这种情况下可以使用下面的方法,虽然可能会被编辑器报语法错误(后续HBuilderX会修复这类误报),但编译到 kotlin 和 swift 时是可用的。

let a:Int =3 //注意目前Int是首字母大写,后续可能会调整
let b:Int =4
let c:Double  = a * 1.0 / b

null

一个表明 null 值的特殊关键字。

有时需定义可为null的字符串,可以在类型描述中使用|操作符。

let user: string | null

注意:uts 编译为kotlin和swift时不支持 undefined。

字面量

字面量是由语法表达式定义的常量;或,通过由一定字词组成的语词表达式定义的常量。

在 uts 中,你可以使用各种字面量。这些字面量是按字面意思给出的固定的值,而不是变量

数组字面量

数组字面值是一个封闭在方括号对 ([]) 中的包含有零个或多个表达式的列表,其中每个表达式代表数组的一个元素。当你使用数组字面值创建一个数组时,该数组将会以指定的值作为其元素进行初始化,而其长度被设定为元素的个数。

布尔字面量

数字字面量

整数字面量

整数可以用十进制(基数为 10)、十六进制(基数为 16)、二进制(基数为 2)表示。

  • 十进制整数字面量由一串数字序列组成,且没有前缀 0。如:0, 117, -345
  • 十六进制整数以 0x(或 0X)开头,可以包含数字(0-9)和字母 af 或 AF。如:0x1123, 0x00111 , -0xF1A7
  • 二进制整数以 0b(或 0B)开头,只能包含数字 0 和 1。如:0b11, 0b0011 , -0b11

浮点数字面量

浮点数字面值可以有以下的组成部分:

  • 一个十进制整数,可以带正负号(即前缀“+”或“ - ”),
  • 小数点(“.”),
  • 小数部分(由一串十进制数表示),
  • 指数部分。

指数部分以“e”或“E”开头,后面跟着一个整数,可以有正负号(即前缀“+”或“-”)。浮点数字面量至少有一位数字,而且必须带小数点或者“e”(大写“E”也可)。

RegExp字面量

字符串字面量

模板字符串

控制流程

三元表达式

三元操作符是右结合的,也就是说你可以像这样把它链接起来, 和 if … else if … else if … else 链类似:

function example(): string {
    return condition1
        ? value1
        : condition2
        ? value2
        : condition3
        ? value3
        : value4;
}

// Equivalent to:

function example(): string {
    if (condition1) {
        return value1;
    } else if (condition2) {
        return value2;
    } else if (condition3) {
        return value3;
    } else {
        return value4;
    }
}

break

使用 break 语句来终止循环,switch。

continue

使用 continue 语句来终止当前循环,并在下一次迭代时继续执行循环。

异常

你可以用 throw 语句抛出一个异常并且用 try...catch 语句捕获处理它。

使用 throw 表达式来抛出异常:

throw new Error("Hi There!");

使用 try……catch 表达式来捕获异常:


try {
    // 一些代码
} catch (e: Error) {
    // 处理程序
} finally {
    // 可选的 finally 块
}

函数

函数作用域

嵌套函数

你可以在一个函数里面嵌套另外一个函数。嵌套(内部)函数对其容器(外部)函数是私有的。它自身也形成了一个闭包。一个闭包是一个可以自己拥有独立的环境与变量的表达式(通常是函数)。

既然嵌套函数是一个闭包,就意味着一个嵌套函数可以”继承“容器函数的参数和变量。换句话说,内部函数包含外部函数的作用域。

可以总结如下:

  • 内部函数只可以在外部函数中访问。
  • 内部函数形成了一个闭包:它可以访问外部函数的参数和变量,但是外部函数却不能使用它的参数和变量。

命名冲突

当同一个闭包作用域下两个参数或者变量同名时,就会产生命名冲突。更近的作用域有更高的优先权,所以最近的优先级最高,最远的优先级最低。这就是作用域链。链的第一个元素就是最里面的作用域,最后一个元素便是最外层的作用域。

举例:

function outside(): (x: number) => number {
    let x = 5;
    const inside = function (x: number): number {
        return x * 2;
    };
    return inside;
}

outside()(10); // 返回值为 20 而不是 10

闭包

uts 允许函数嵌套,并且内部函数可以访问定义在外部函数中的所有变量和函数,以及外部函数能访问的所有变量和函数。

但是,外部函数却不能够访问定义在内部函数中的变量和函数。这给内部函数的变量提供了一定的安全性。

此外,由于内部函数可以访问外部函数的作用域,因此当内部函数生存周期大于外部函数时,外部函数中定义的变量和函数的生存周期将比内部函数执行时间长。当内部函数以某一种方式被任何一个外部函数作用域访问时,一个闭包就产生了。

举例:

const pet = function (name: string): () => string {
    //外部函数定义了一个变量"name"
    const getName = function (): string {
        //内部函数可以访问 外部函数定义的"name"
        return name;
    };
    //返回这个内部函数,从而将其暴露在外部函数作用域
    return getName;
};
const myPet = pet("Vivie");
myPet(); // 返回结果 "Vivie"

类(class)

uts 中使用关键字 class 声明类

内置对象和API

uts 有一批内置对象。不管将 uts 编译为 js/kotlin/swfit,这些内置对象都可以跨平台使用

console

#debug

在控制台打印 debug 日志

console.debug(msg1, msg2, msg3)

#error

在控制台打印 error 日志

console.error(msg1, msg2, msg3)

#info

在控制台打印 info 日志

console.info(msg1, msg2, msg3)

#log

在控制台打印 log 日志

console.log(msg1, msg2, msg3)

#warn

在控制台打印 warn 日志

console.warn(msg1, msg2, msg3)

Array

Array 对象是用于构造数组的全局对象,数组是类似于列表的高阶对象

实例属性

length

实例方法

concat

concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组

copyWithin

copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度

const array1 = ['a', 'b', 'c', 'd', 'e'];
// copy to index 0 the element at index 3
console.log(array1.copyWithin(0, 3, 4));
// expected output: Array ["d", "b", "c", "d", "e"]
// copy to index 1 all elements from index 3 to the end
console.log(array1.copyWithin(1, 3));
// expected output: Array ["d", "d", "e", "d", "e"]

every

every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值

fill

fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引

const array1 = [1, 2, 3, 4];

// fill with 0 from position 2 until position 4
console.log(array1.fill(0, 2, 4));
// expected output: [1, 2, 0, 0]

// fill with 5 from position 1
console.log(array1.fill(5, 1));
// expected output: [1, 5, 5, 5]

console.log(array1.fill(6));
// expected output: [6, 6, 6, 6]

filter

filter() 方法创建一个新数组,其包含通过所提供函数实现的测试的所有元素

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter((word:string):boolean => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

find

find() 方法返回数组中满足提供的测试函数的第一个元素的值

findIndex

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1

flat

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回

const arr1 = [0, 1, 2, [3, 4]];

console.log(arr1.flat());
// expected output: [0, 1, 2, 3, 4]

const arr2 = [0, 1, 2, [[[3, 4]]]];

console.log(arr2.flat(2));
// expected output: [0, 1, 2, [3, 4]]

forEach

forEach() 方法对数组的每个元素执行一次给定的函数。

const array1 = ['a', 'b', 'c'];
array1.forEach(element => console.log(element));
// expected output: "a"
// expected output: "b"
// expected output: "c"

includes

includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。

const array1 = [1, 2, 3];

console.log(array1.includes(2));
// expected output: true

const pets = ['cat', 'dog', 'bat'];

console.log(pets.includes('cat'));
// expected output: true

console.log(pets.includes('at'));
// expected output: false

indexOf

indexOf() 方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1

join

join() 方法将一个数组的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符

lastIndexOf

lastIndexOf() 方法返回指定元素在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始

map

map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成

pop

pop() 方法从数组中删除最后一个元素,并返回该元素的值。此方法会更改数组的长度

push

push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度

reduce

reduce() 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 initialValue,迭代器将从第二个元素开始执行(索引为 1 而不是 0)。

const array1 = [1, 2, 3, 4];

// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
  (previousValue:number, currentValue:number):number => previousValue + currentValue,
  initialValue
);

console.log(sumWithInitial);
// expected output: 10

shift

shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

slice

slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。

some

some() 方法测试数组中是不是至少有 1 个元素通过了被提供的函数测试。它返回的是一个 Boolean 类型的值。

splice

splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

unshift

unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)

Date

创建一个 Date 实例,该实例呈现时间中的某个时刻。Date 对象则基于 Unix Time Stamp,即自 1970 年 1 月 1 日(UTC)起经过的毫秒数

静态方法

now

平台差异说明

WebKotlinSwift
x

JSON

静态方法

parse

JSON.parse() 方法用来解析 JSON 字符串,构造由字符串描述的 UTSJSONObject。

const json = `{"result":true, "count":42}`;
const obj = JSON.parse(json);

console.log(obj["count"]);
// expected output: 42

console.log(obj["result"]);
// expected output: true

注意

  • JSON.parse 解析出来的对象,目前仅支持使用方括号[]访问

stringify

JSON.stringify() 方法将一个 uts 对象或值转换为 JSON 字符串

Map

Map 对象保存键值对。任何值(对象或者基本类型)都可以作为一个键或一个值

Number

Number 对象是经过封装的能让你处理数字值的对象 平台差异说明

WebKotlinSwift
x

Set

Set 对象是值的集合,你可以按照插入的顺序迭代它的元素。Set 中的元素只会出现一次,即 Set 中的元素是唯一的 平台差异说明

WebKotlinSwift
x

String

String 全局对象是一个用于字符串或一个字符序列的构造函数

定时器

setTimeout

而 uts 的类型系统,可以在很大程度上弥补 JavaScript 的缺点。

uts 是静态类型

类型系统按照「类型检查的时机」来分类,可以分为动态类型和静态类型。

动态类型是指在运行时才会进行类型检查,这种语言的类型错误往往会导致运行时错误。JavaScript 是一门解释型语言,没有编译阶段,所以它是动态类型,以下这段代码在运行时才会报错:

静态类型是指编译阶段就能确定每个变量的类型,这种语言的类型错误往往会导致语法错误。uts 在编译阶段就会进行类型检查,所以 uts 是静态类型,这段 uts 代码在编译阶段就会报错了:

大部分 JavaScript 代码只需要经过少量的修改,增加类型批注,就可以变成 uts 代码,这跟 ts 非常接近