LiteJSE Javascript 编程指南
更新时间:2018-09-18 10:10:19
针对硬件资源不同的嵌入式设备,TinyEngine
提供两种不同的JSE(LiteJSE
和DuktapeJSE
),其中 LiteJSE
是阿里巴巴自主开发JSE,目标是运行在资源非常有限的MCU或硬件,所耗资源 RAM<15KB,ROM<15KB,但支持的JS语法有限;另一种是DuktapeJSE
,DuktapeJSE
支持Javascript
到 ES5.1,DuktapeJSE
采用开源项目 duktape 。
如需要支持Javascript
语法强的应用场景,或者RAM/ROM资源不是很敏感(RAM>256KB)的嵌入式设备,建议选用DuktapeJSE
。
LiteJSE Javascript 语法支持列表
|
支持
|
不支持
|
备注
|
词法
|
空白字符
行终结符
注释
Tokens
标识符名和标识符
保留字
字面量
自动分号插入
|
Unicode 格式控制字符
正则表达式字面量
|
声明变量/常量时,变量名/值表达式命名最长为63个字符
定义函数原型时,参数名称不要超过7个字符
|
类型
|
undefined
null
true、false
string
Number 类型(整数、浮点数、指数)
Object类型
列表规范类型
完结规范类型
属性描述符及属性标识符规范类型
|
Infinity
NaN
Object 内部属性
引用规范类型
词法环境和环境记录项规范类型
对象内部方法的算法
|
支持二进制/八进制/十六进制
|
类型转换
|
SameValue 算法
|
ToPrimitive
ToBoolean
ToNumber
ToInteger
ToInt32
ToUint32
ToUint16
ToString
ToObject
CheckObjectCoercible
IsCallable
|
可根据需要扩展支持
|
表达式
|
主值表达式
左值表达式
后缀表达式(++,--)
一元运算符 (部份支持)
乘法运算符
加法运算符
位运算移位运算符
比较运算符
in 运算符
等值运算符
严格等于运算符 ( === ) 严格不等于运算符 ( !== )
二元逻辑运算符
条件运算符
赋值运算符
逗号运算符
|
delete 运算符
void 运算符
typeof 运算符
instanceof 运算符
二进制位运算符
|
|
语句
|
块
变量语句
空语句
表达式语句
if 语句
迭代语句
for-in 语句 continue 语句 break 语句 with 语句 switch 语句
return 语句
|
do-while 语句
标签语句
throw 语句
try 语句
debugger 语句
|
default必须在最后一个case之后且default不能使用break结束字
|
全局对象
|
undefined
全局对象的函数属性(部份支持)
eval (x)
全局对象的构造器属性 (部份支持)
|
NaN
Infinity
parseInt (string , radix)
parseFloat (string)
isNaN (number)
isFinite (number)
处理 URI 的函数属性
|
|
Object 对象
|
作为函数调用 Object 构造器
Object 构造器
|
Object 构造器的属性
Object 的 prototype 对象的属性
|
|
Function 对象
|
Function 对象
Function 构造器
|
Function 构造器
Function 的 prototype 对象的属性
Function 的实例的属性
|
|
Array 对象
|
作为函数调用 Array 构造器
Array 构造器
数组原型对象的属性 (部份支持)
Array.prototype.contains(element)
Array.prototype.indexOf(searchElement)
Array.prototype.push(element)
Array.prototype.pop()
Array.length
|
Array 构造器的属性
[[GetOwnProperty]] ( P )
|
可根据需求扩充
|
String 对象
|
作为函数调用 String 构造器
String 构造器
字符串原型对象的属性(部份支持)
String.prototype.charAt (pos)
String.prototype.substring (start, end)
String.prototype.substr(start[, length])
String.prototype.str.indexOf(searchValue)
String.length
|
String 构造器的属性
|
可根据需求扩充
|
Math 对象
|
random ( )
|
|
可根据需求扩充
|
Date 对象
|
|
Date 对象
|
|
RegExp 对象
|
|
RegExp ( 正则表达式 ) 对象
|
|
Error 对象
|
|
Error Objects 不支持
|
|
JSON 对象
|
JSON 语法
parse (text)
stringify(value)
|
可根据需求扩充
|
LiteJSE Javascript 编写示例
基本语法示例
// 数值类型,变量,支持整数、浮点数、指数、八进制数、十六进制数、二进制数
var a = 345;
var b = 34.5;
var c = 3.45e2;
var d = 0377;
var e = 0xFF;
var f = 0b111;
var result = a==345 && b*10==345 && c==345 && d==255 && e==255 && f==7;
console.log('Number 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// 值:undefined/null
var testUndefined; // variable declared but not defined, set to value of undefined
var testObj = {};
var a = 0;
if ((""+testUndefined) != "undefined") a = 1; // test variable exists but value not defined, displays undefined
if ((""+testObj.myProp) != "undefined") a = 2; // testObj exists, property does not, displays undefined
if (!(undefined == null)) a = 3; // unenforced type during check, displays true
if (undefined === null) a = 4;// enforce type during check, displays false
if (null != undefined) a = 5; // unenforced type during check, displays true
if (null === undefined) a = 6; // enforce type during check, displays false
if (undefined != undefined) a = 7;
if (!(undefined == undefined)) a = 8;
var b = undefined;
if (b !=undefined ) a = 9; // check for undefined
result = a==0;
console.log(testUndefined);
console.log('undefined/null 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// Variable creation and scope from http://en.wikipedia.org/wiki/JavaScript_syntax
x = 0; // A global variable
var y = 'Hello!'; // Another global variable
z = 0; // yet another global variable
function f(){
var z = 'foxes'; // A local variable
twenty = 20; // Global because keyword var is not used
return x; // We can use x here because it is global
}
// The value of z is no longer available
// testing
blah = f();
result = blah==0 && z!='foxes' && twenty==20 && (z==undefined);
console.log('变量及作用域 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// if .. else
var a = 42;
if (a != 42)
result = 0;
else
result = 1;
console.log('if else 测试 ' + ((result == 1 ) ? '成功' : '失败'));
function Person(name) {
this.name = name;
this.kill = function() { this.name += " is dead"; };
}
var a = new Person("Kenny");
a.kill();
result = a.name == "Kenny is dead";
console.log('简单对象 测试 ' + ((result == 1 ) ? '成功' : '失败'));
obj1 = new Object();
obj1.food = "cake";
obj1.desert = "pie";
// 仅支持支持string 及 无传参的object对象的clone
obj2 = obj1.clone();
obj2.food = "kittens";
result = obj1.food=="cake" && obj2.desert=="pie";
console.log('简单对象 测试 ' + ((result == 1 ) ? '成功' : '失败'));
var Foo = {
value : function() { return this.x + this.y; }
};
var a = { prototype: Foo, x: 1, y: 2 };
var b = new Foo();
b.x = 2;
b.y = 3;
var result1 = a.value();
var result2 = b.value();
result = result1==3 && result2==5;
console.log('嵌套对象 测试 ' + ((result == 1 ) ? '成功' : '失败'));
/*
r = Math.random();
console.log('Math.random 测试 ' + ((result = r != undefined ) ? '成功' : '失败'));
parsed = Integer.parseInt("42");
aChar = 'A';
result = parsed==42 && Integer.valueOf(aChar)==65 ;
console.log('Integer.parseInt/valueOf 测试 ' + ((result == 1 ) ? '成功' : '失败'));
*/
// test for shift
var a = (2<<2);
var b = (16>>3);
/*
// >>> (无符号右移) 暂不支持
var c = (-1 >>> 16);
*/
result = a==8 && b==2;
console.log('移位操作 测试 ' + ((result == 1 ) ? '成功' : '失败'));
var a=5.0/10.0*100.0;
var b=5.0*110.0;
var c=50.0/10.0;
result = a==50 && b==550 && c==5;
console.log('浮点数除法 测试 ' + ((result == 1 ) ? '成功' : '失败'));
var a =2;
var b=5;
var c=6;
result = ((!a*b+a*10+a*b*c) == 80);
console.log('乘法/非操作 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// 只支持后缀自增运算符
var a = 5;
var b = 5;
result = ((a++)==5) && (a==6) && ((b--) == 5) && (b==4);
console.log('后缀自增运算符 ++/-- 测试 ' + ((result == 1 ) ? '成功' : '失败'));
/*
当前语法不支持
var a = 5;
var b = 5;
result = ((++a)==6) && (a==6) && ((--b) == 4) && (b==4);
console.log('前置型 ++/-- 测试 ' + ((result == 1 ) ? '成功' : '失败'));
*/
/* Javascript eval */
// 对象转换需要加()
myfoo = eval("({ foo: 42 })");
result = eval("4*10+2")==42 && myfoo.foo==42;
console.log('eval 测试 ' + (result ? '成功' : '失败'));
/* Javascript eval */
mystructure = { a:39, b:3, addStuff : function(c,d) { return c+d; } };
mystring = JSON.stringify(mystructure);
mynewstructure = eval("("+mystring+")");
result = mynewstructure.addStuff(mynewstructure.a, mynewstructure.b) == 42;
console.log('eval 测试 ' + (result ? '成功' : '失败'));
var array = JSON.parse('[1,2,3,true]');
console.log('JSON.parse 测试 ' + (array.length==4 ? '成功' : '失败'));
console.log(array);
var obj = JSON.parse('{"name":"alibaba","age":18}');
console.log('JSON.parse 测试 ' + (obj.age==18 ? '成功' : '失败'));
console.log(obj.name);
/*
模块测试, Modules.addCached 通过JS程序注册模块,代替从文件中读取
*/
var count=0;
Modules.addCached("a","module.exports.foo=1;");
var ta = require("a").foo;
count += ta;
console.log('ta=' + ta);
Modules.addCached("b","module.exports = {foo:1};");
var tb = require("b").foo;
count += tb;
console.log('tb=' + tb);
Modules.addCached("c","module.exports = 1;");
var tc = require("c");
count += tc;
console.log('tc=' + tc);
Modules.addCached("d","exports.foo = 1;");
var td = require("d").foo;
count += td;
console.log('td=' + td);
Modules.addCached("e","exports.foo = function(){ return 1;};");
var te = require("e").foo();
count += te;
console.log('te=' + td);
console.log(count);
console.log('Modules.addCache 测试' + ( (count == 5) ? '正确' : '失败'));
var myModule = "function myModule() {" +
" this.hello = function() {" +
" return 'hello!'; " +
" }; " +
" this.goodbye = function() {" +
" return 'goodbye!';" +
" }; " +
"}; " +
"module.exports = myModule; " ;
//console.log('myModule=' + myModule);
Modules.addCached("myModule", myModule);
myModule = require('myModule');
var myModuleInstance = new myModule();
console.log(myModuleInstance.hello());
console.log(myModuleInstance.goodbye());
var linkModule = " " +
"var mac = 'abc'; " +
"function Link() { " +
" this.uuid = '1234';" +
"};" +
"var mLink = new Link();" +
"mLink.start = function(){" +
" return this.uuid + ' start';" +
"};" +
"module.exports.Link = mLink;" +
"module.exports.mac = mac;";
Modules.addCached("linkModule", linkModule);
linkModule = undefined;
link = require('linkModule').Link;
console.log(link.start());
console.log(require('linkModule').mac);
// 验证module所分符号表使用无异常
/*
for(i=0; i<100; i++){
console.log(link.start());
console.log(require('linkModule').mac);
console.log('te=' + require("e").foo());
console.log('td=' + require("d").foo);
}
*/
字符串相关语法示例
foo = "foo bar stuff";
aStr = "ABCD";
aChar = aStr.charAt(0);
value = Integer.valueOf(aChar);
result = foo.length==13 && foo.indexOf("bar")==4 &&
foo.substring(8,13)=="stuff" && foo.substr(-3) == "uff" && aChar == 'A' &&
Integer.valueOf(aChar)==65;
console.log('string 测试 ' + (result ? '成功' : '失败'));
function toMethod(event)
{
var i;
var j = event.length;
var ch;
var ret = '';
for(i=0; i<j; i++){
ch = event.charAt(i);
if( ch == '/' )
ret = ret + '.';
else
ret = ret + ch;
}
return ret;
}
var events = [
"thing/event/property/post"
];
result = ( 'thing.event.property.post' == toMethod(events[0]) )
console.log('string 测试 ' + (result ? '成功' : '失败'));
console.log( toMethod(events[0]) );
数组相关语法示例
//变量有两种类型的值,即原始值和引用值。
// ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String
// array 是引用值变量
var a = [];
a[0] = 10;
a[1] = 22;
b = a;
b[0] = 5;
result = a[0]==5 && a[1]==22 && b[1]==22;
console.log('array引用传递 测试 ' + (result ? '成功' : '失败'));
// Array length test
myArray = [ 1, 2, 3, 4, 5 ];
myArray2 = [ 1, 2, 3, 4, 5 ];
myArray2[8] = 42;
result = myArray.length == 5 && myArray2.length == 9;
console.log('array length 测试 ' + (result ? '成功' : '失败'));
// test for array contains
var a = [1,2,4,5,7];
var b = ["bread","cheese","sandwich"];
result = a.contains(1) && !a.contains(42) && b.contains("cheese") && !b.contains("eggs");
console.log('array contains 测试 ' + (result ? '成功' : '失败'));
// Array.indexOf
var a = [8,9,10];
a["foo"]="lala";
a[3.333] = 3;
var r = [
a.indexOf(8),
a.indexOf(10),
a.indexOf(42)
];
result = r[0]==0 && r[1]==2 && r[2]==undefined;
console.log('array indexOf 测试 ' + (result ? '成功' : '失败'));
var a = [1,2];
a.push(3);
a.push(4);
a.push('ok5');
a.push(6);
a.pop();
result = (a.length == 5) && (a.indexOf(2) == 1) && a.contains('ok5') && (!a.contains(6)) ;
console.log('array push/pop 测试 ' + (result ? '成功' : '失败'));
// 支持数组 in 操作
var x;
for (x in a)
{
console.log('a[' + x + ']=' + a[x]);
}
if( 4 in a )
console.log('4 in a , sucess');
/*
// test for array remove
var a = [1,2,4,5,7];
// 不支持object.remove
a.remove(2);
a.remove(5);
result = a.length==3 && a[0]==1 && a[1]==4 && a[2]==7;
// test for array join
var a = [1,2,4,5,7];
// join 不支持
result = a.join(",")=="1,2,4,5,7";
*/
循环及分支语法示例
// simple for loop
var a = 0;
var i;
for (i=1;i<10;i++)
a = a + i;
result = a==45;
console.log('for循环测试 ' + ((result == 1 ) ? '成功' : '失败'));
// simple for loop containing initialisation, using +=
var a = 0;
for (var i=1;i<10;i++)
a += i;
result = a==45;
console.log('for循环 += 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// test break
var c1=0;
var c2=0;
var c3=0;
for (i=0;i<10;i++) {
if (i>4) break;
c1++;
}
for (i=0;i<10;i++) {
c2++;
if (i>4) break;
}
for (j=0;j<10;j++) {
for (i=0;i<10;i++) {
if (i>4) break;
c3++;
}
c3++;
}
result = (c1==5) && (c2==6) && (c3==10+5*10);
console.log('break测试 ' + ((result == 1 ) ? '成功' : '失败'));
// test continue
var c1=0;
var c3=0;
for (i=0;i<10;i++) {
if (i>4 && i<8) continue;
c1++;
}
for (j=0;j<10;j++) {
for (i=0;i<10;i++) {
if (i>4 && i<8) continue;
c3++;
}
c3++;
}
result = (c1==7) && (c3==10+7*10);
console.log('continue测试 ' + ((result == 1 ) ? '成功' : '失败'));
// switch-case-tests
////////////////////////////////////////////////////
// switch-test 1: case with break;
////////////////////////////////////////////////////
var a1=5;
var b1=6;
var r1=0;
switch(a1+5){
case 6:
r1 = 2;
break;
case b1+4:
r1 = 42;
break;
case 7:
r1 = 2;
break;
}
console.log('switch case break测试 ' + ((result = r1 == 42 ) ? '成功' : '失败'));
////////////////////////////////////////////////////
// switch-test 2: case with out break;
////////////////////////////////////////////////////
var a2=5;
var b2=6;
var r2=0;
switch(a2+4){
case 6:
r2 = 2;
break;
case b2+3:
r2 = 40;
//break;
case 7:
r2 += 2;
break;
}
console.log('switch 缺少break 测试 ' + ((result = r2 == 42 ) ? '成功' : '失败'));
////////////////////////////////////////////////////
// switch-test 3: case with default;
////////////////////////////////////////////////////
var a3=5;
var b3=6;
var r3=0;
switch(a3+44){
case 6:
r3 = 2;
break;
case b3+3:
r3 = 1;
break;
default:
r3 = 42;
}
console.log('switch default 测试 ' + ((result = r3 == 42 ) ? '成功' : '失败'));
/*
// switch-test 4: case default before case; 语法分析出错
default必须在最后一个case之后且default不能使用break结束字
var a4=5;
var b4=46;
var r4=40;
switch(a4+44){
default:
r4 = 42;
case 6:
r4 = 2;
break;
case b4+3:
r4 = 1;
break;
}
console.log('switch default before case 测试 ' + ((result = r4 == 42 ) ? '成功' : '失败'));
*/
函数相关语法示例
// simple function
var b = function(x)
{
return x;
};
var a = b(10)+b(20);
function add(x,y)
{
return x+y;
}
var result;
result = (a == 30) && (add(3,6)==9);
console.log('简单函数测试 ' + ((result == 1 ) ? '成功' : '失败'));
// simple function scoping test
var a = 7;
function add(x,y) { var a=x+y; return a; }
result = add(3,6)==9 && a==7;
console.log('简单函数+作用域 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// functions in variables
var bob = {};
bob.add = function(x,y) { return x+y; };
result = bob.add(3,6)==9;
console.log('对象函数 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// functions in variables using JSON-style initialisation
var bob = { add : function(x,y) { return x+y; } };
result = bob.add(3,6)==9;
console.log('JSON描述对象函数 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// double function calls
function a(x) { return x+2; }
function b(x) { return a(x)+1; }
result = a(3)==5 && b(3)==6;
console.log('嵌套调用函数 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// recursion
function a(x) {
if (x>1)
return x*a(x-1);
return 1;
}
result = a(5)==1*2*3*4*5;
console.log('嵌套调用函数 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// references with functions
// 函数参数变量可以存在两种类型的值,即原始值和引用值。
// ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String
var a = 42;
var b = [];
b[0] = 43;
function foo(myarray) {
myarray[0]++;
}
function bar(myvalue) {
myvalue++;
}
foo(b);
bar(a);
result = a==42 && b[0]==44;
console.log('函数参数 原始值和引用值 测试 ' + ((result == 1 ) ? '成功' : '失败'));
// 全局变量及作用域
z = 0;
function addstuff() {
var count=0;
z = function() {
count++;
return count;
};
}
addstuff();
result = z();
//console.log(count); // BoneEngine > undefined
console.log(result);
console.log('全局变量及作用域 测试 ' + ((result == 1 ) ? '成功' : '失败'));
var func = addstuff;
console.log(func); // BoneEngine > function
if( func )
console.log('if判断函数 sucess');
else
console.log('if判断函数 fail');