开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情
SJS介绍
对数据进行处理,减少逻辑层与渲染层之间的频繁交互
SJS(Safe/Subset JavaScript)是小程序定义的一套脚本语言,由它导出的变量/函数可以 [在
AXML
中使用]。
语法定义
SJS 是 JavaScript 语言的子集,并不等同于 JavaScript
模块管理
- SJS 文件的扩展名必须为
.sjs
,每个 .sjs 文件为一个模块,使用 export 导出变量和函数,使用 import 引入依赖的其他 SJS 模块(请勿省略文件扩展名)。 - SJS 也可引用 npm 包,但只能引用其中的 .sjs 文件。 运行环境
- SJS 运行在小程序渲染层,与小程序的 JavaScript 运行环境(逻辑层)隔离,因而不能调用 JS 文件中定义的函数,也不能调用小程序提供的 API。
- SJS 中定义的函数可用于响应基础组件的事件以避免逻辑层和渲染层的频繁通信,但有一定的限制
使用示例
文件名后缀必须是.sjs
export default进行输出
通过import进行引入
渲染结果:
作用
主要是对数据进行处理。避免逻辑层和渲染层的频繁通信。从而提升一定的性能,还可以响应基础组件的事件。
变量
语法规则
var
与 JavaScript 中表现一致,会有变量提升。- 支持 const 与 let,与 JavaScript 表现一致。
- 只声明变量而不赋值,默认值为
undefined
。
命名规则
变量命名必须符合下面两个规则:
- 首字符必须是:字母(a-z,A-Z),下划线(_)。
- 首字母以外的字符可以是:字母(a-z,A-Z),下划线(_),数字(0-9)。
示例:
用标签import-sjs的form属性输入路径来引入,通过name属性来定义名称,使用时通过路径来直接使用即可。
注释
运算符
运算符优先级
SJS 运算符的优先级与 JavaScript 一致。
语句
if语句
在 .sjs 文件中,可以使用以下格式的 if 语句 :
- if (expression) statement : 当 expression 为 truthy 时,执行 statement。
- if (expression) statement1 else statement2 : 当 expression 为 truthy 时,执行 statement1。 否则,执行 statement2。
- if ... else if ... else statementN 通过该句型,可以在 statement1 ~ statementN 之间选其中一个执行。
Switch语句
default
分支可以省略不写。
case
关键词后面只能使用:变量
,数字
,字符串
for语句
支持使用
break
,continue
关键词。
while语句
- 当
表达式
为 true 时,循环执行语句
或代码块
。
- 支持使用
break
,continue
关键词
数据类型
SJS 目前支持如下数据类型:
- string:字符串。
- boolean:布尔值。
- number:数值。
- object:对象。
- function:函数。
- array:数组。
- date:日期。
- regexp:正则表达式。
判断数据类型
SJS 提供了 constructor 与 typeof 两种方式判断数据类型。
SJS 响应事件
复杂的交互场景下,如果通过 setData 去更新视图,体验上较为卡顿。
例如,要实现元素跟随用户手指拖动而移动的效果,需要经过如下响应过程:
- 用户手指移动,触发基础组件的 touchMove 事件,web-view 将该事件通信到 worker。
- worker 执行该事件回调,并 setData 更新数据。
- web-view 收到数据更新信息,进而改变元素样式,实现元素移动。
上述过程中,web-view 和 worker 之间的来回通信耗时较大,不满足高性能和极速响应的要求。
因此,要支持此种富交互场景,必须减少通信次数,允许在 web-view 侧直接响应事件。SJS 函数支持响应基础组件的事件,无需数据更新,可直接驱动视图元素的样式、类名等的变更,也可查询元素的布局信息等
selector 语法
selector 类似于 CSS 的选择器,但仅支持下列语法。
- ID 选择器:#the-id。
- class 选择器(可以连续指定多个):.a-class.another-class。
- 子元素选择器:.the-parent > .the-child。
- 后代选择器:.the-ancestor .the-descendant。
- 跨自定义组件的后代选择器:.the-ancestor >>> .the-descendant(基础库 [2.7.3] 起支持)。
- 多选择器的并集:#a-node, .some-other-nodes。
判定 >>>
选择器是否可用,可通过如下方法查询:
示例代码:
事件回调
接受两个参数:
1. event.preventDefault()
对于限定的以下事件:
- touchStart
- touchMove
- touchEnd
- touchCancel
可以通过 event.preventDefault() 阻止 web-view 中的事件默认行为。
其它事件(如 tap 等)调用此方法无效。
2. event.stopPropagation()
阻止该事件继续向父基础组件触发。等同于使用了 catch* 事件回调。
3. 自定义组件/页面 Descriptor 描述对象
SJS 函数的第二个参数 ownerComponent 指向该事件 event.currentTarget 所在的自定义组件/页面的 Descriptor 对象,具有如下方法:
4. 基础组件 Descriptor 描述对象
通过 event.instance 可以获得 event.currentTarget 的 Descriptor 描述对象,除了上述自定义组件/页面的方法外,还具有如下方法:
5. composedPath()
基础库 [2.7.3]) 起支持,获取事件路径。返回值为数组,数组的元素为基础元素的 Descriptor 描述对象。使用插件时,宿主小程序内的事件路径会跳过属于插件的描述对象,插件内的事件路径也会跳过属于宿主小程序的描述对象。
返回值
当 SJS 函数返回布尔值 false 时,等同于同时调用:
- event.preventDefault()
- event.stopPropagation()
属性监听
基础组件初始化时会立即回调一次监听函数。当被监听属性值更新后,即新旧值不相等时,会再次触发回调。
示例代码: