# 数据绑定表达式

数据绑定 `{{ ... }}` 内部的表达式，可以使用大部分 JS 运算符。

一个复杂表达式的例子：

```html
<view>{{ a !== 0 ? 'Number: ' + a : 'Zero' }}</view>
```

## 关键字

部分标识符被视为关键字，它们不被视为数据字段。这些关键字的含义和 JS 中的相同。

| 关键字 |
| ------ |
| `undefined` |
| `null` |
| `false` |
| `true` |

## 字面量

支持字面量有以下几种。

| 字面量类型 | 示例 |
| ---------- | ---- |
| 字符串 | `"示例字符串"` `'示例字符串'` |
| 数值 | `2017` `1.9` |
| 数组字面量 | `[ 1, 2, 34 ]` |
| 对象字面量 | `{ a: 1, b, c: 3 + 4 }` |

数组字面量、对象字面量内可以使用 `...` 展开其他数组、对象。

## 对象字面量简写

> glass-easel 组件框架完全支持对象字面量简写；对于 exparser 组件框架，只有 template data 可以使用对象字面量简写。

如果数据绑定表达式完全就是一个对象字面量，那可以省略对象字面量的花括号 `{` `}`。

```html
<view mark:ab="{{ a: 1, b }}" />
<!-- 等价于 -->
<view mark:ab="{{ { a: 1, b } }}" />
```

## 支持的运算符列表

以下是支持的运算符列表。各个运算符语义与 JS 中的相同。

| 分类 | 运算符 | 示例 | 附注 |
| ---- | ------ | ---- | ---- |
| 成员访问和函数调用 | `.` | `obj.field` |  |
|  | `[...]` | `obj[field]` |  |
|  | `(...)` | `func(arg1, arg2)` | 请参考 函数调用限制 |
| 一元运算 | `!` | `!cond` |  |
|  | `~` | `~int` |  |
|  | `+` | `+num` |  |
|  | `-` | `-num` |  |
|  | `typeof` | `typeof value` | 仅 glass-easel 组件框架支持 |
|  | `void` | `void value` | 仅 glass-easel 组件框架支持 |
| 乘除 | `*` | `a * b` |  |
|  | `/` | `a / b` |  |
|  | `%` | `a % b` |  |
| 加减 | `+` | `a + b` |  |
|  | `-` | `a - b` |  |
| 移位运算 | `<<` | `int << 2` |  |
|  | `>>` | `int >> 2` |  |
|  | `>>>` | `int >>> 2` |  |
| 大小比较 | `<` | `a < b` |  |
|  | `>` | `a > b` |  |
|  | `<=` | `a <= b` |  |
|  | `>=` | `a >= b` |  |
|  | `instanceof` | `value instanceof type` | 仅 glass-easel 组件框架支持 |
| 相等判断 | `==` | `a == b` |  |
|  | `!=` | `a != b` |  |
|  | `===` | `a === b` |  |
|  | `!==` | `a !== b` |  |
| 按位与 | `&` | `int1 & int2` |  |
| 按位异或 | `^` | `int1 ^ int2` |  |
| 按位或 | `\|` | `int1 \| int2` |  |
| 逻辑与 | `&&` | `a && b` |  |
| 逻辑或和空值合并 | `\|\|` | `a \|\| b` |  |
|  | `??` | `a ?? b` | 仅 glass-easel 组件框架支持 |
| 条件运算 | `? ... :` | `a ? b : c` |  |

## 自动可选链化

成员访问和函数调用运算符，会自动转换成他们的可选链版本。

* `.` 被自动视为 `?.`
* `[...]` 被自动视为 `?.[...]`
* `(...)` 被自动视为 `?.(...)`

因此不需要写可选链运算符 `?.`。若访问 `undefined` 或 `null` 的成员，表达式结果为 `undefined`。

## 函数调用限制

可以使用 `(...)` 来进行函数调用。但函数调用有一定的限制和注意事项。

* 组件框架执行模板中函数的时机是不确定的，可能在运行期间的任何时候调用函数，也可能会跳过函数调用。
* 参数列表中不能使用 `...`。
* 在 exparser 组件框架中，只有 WXS 中定义的函数能被调用。
* 目前，在 glass-easel 组件框架中使用非 WXS 中定义的函数时，任何参数和返回值类型都不能是对象或函数，只能是字符串、数值、布尔等简单类型。
