- 浏览: 961316 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
sscsacdsadcsd:
mike8625 写道react还要自己的一些标签 还得编译 ...
对于React体系的一点想法 -
mike8625:
说的都是给大公司听的,国内很多还是小公司,做个小项目, 说实话 ...
关于国内前端和JS技术发展的乱想 -
mike8625:
react还要自己的一些标签 还得编译 编译吧浏览器端说还慢 ...
对于React体系的一点想法 -
u012814086:
下意识想到了Golang
JavaScript语句后应该加分号么? -
xueduanyang:
我是水羊,年轻的时候觉得只要有好斧子就能做成好产品,各种产品都 ...
关于国内前端和JS技术发展的乱想
【2011年7月12日更新】
本文所述的“with”转换方式存在一些缺点,请进一步阅读如何将let结构(block scope)转换到当前的JavaScript代码
以下是2008年11月的原文。
JavaScript 1.7开始加入了let结构。你可以在FF2以上开启let的支持:
<script type="application/javascript;version=1.7">...</script>
我们知道JS虽然是近似lexical scope,但是并非真正lex scope。其中一点就是ES3的spec所确定的scope chain机制,只作用到function这一层(虽然内部还有with和catch的特例),因此JS只有function scope而没有block scope。对于习惯block scope的程序员来说这带来一些微妙的bug隐患。比如:
在for循环中的var x定义,并不会为每次循环产生一个不同的x引用,所有的x其实都是一个,就是在for循环所属的函数的scope下的唯一的那个x。因而如果你在每次循环中产生一个不同的闭包(比如为一系列元素设置事件处理器),并在闭包中引用了x的话,这个x并不会像程序员所期望的那样对应循环当时的x,所有的闭包中的x最后都指向到相同的那个x,当你运行闭包时,其值就必然是x在最后一次循环时所赋值(在上面这个例子中就是f[0]到f[9]的调用结果一律为900)。这种行为让许多程序员感到难以理解。
let的引入就是为了解决这个问题,甚至因此牺牲了向前兼容性,因为let是关键字,而老的程序可能用let作为变量名。为保持向前兼容性,导致你必须在script元素中明确声明version来启用let(以及其他无法向前兼容的)特性。
let的例子如下:
A. let语句:
B. let表达式
C. let定义
A和B的输出结果都是27,5。
C和之前所举的例子完全一样,除了for内部从var x改为了let x。而此时f[0]()到f[9]()的调用结果就和我们期望的一样,为0,100,200直到900。
下面我来讨论一下,如何在现有的ES3的引擎中模拟let的行为。如果是手写代码,自然可以规避let的问题。不过这里讨论的是有没有可能找到一个模式可以套用,这样就可以将含有let结构的代码自动转换为可在现有ES3引擎中正确执行的代码。
A. let语句转换为一层function调用:
B. let表达式转换为一层function调用:
C. let定义转换为一层function调用:
这样看似就OK了。然而其实还有问题。比如,如果包含了this关键字呢?
如果依样画葫芦改为:
是不行的。
需要改为这样:
但是这也不解决所有问题,如果是夹杂控制跳转语句的话怎么办?
比如
在scope中如果存在跳转到block之外的语句,那直接套用一层函数是不行的。
一种解决方法是,让函数返回特定值,然后处理之。如:
然而,这种方法较为复杂,需要处理continue、break、return和throw语句,尤其是多层嵌套和带有label的跳转,需要识别出哪些语句是跳转到本block之外,并只对这些语句进行转换。为此必须对程序进行完整的解析。
有没有更轻便的方法?
这本来是mission impossible,然而JS的lexical scope留了个后门,那就是with。with可以在现有的scope chain头上附加一层binding。有了with我们不难得到A和C的等价形式(B是let表达式,还是转换为function更方便):
A. let语句转换为with:
C. let定义转换为with:
容易看出,改为with结构没有this引用的问题。更重要的是with只是一个statement,其中的continue、break、return、throw语句一律不会受到影响。
不过事情没有完美的。with的问题是,按照ES3规范来说,with语句中(if语句、for语句等)是不能有function声明的(但是允许function表达式)。不过如果你这样干了,现有的JS引擎大多并不会报错,但是在行为上有所差异。
在IE(JScript)中,with对函数声明的scope不会有影响,所以输出结果为:
B1
B1
B1
B2
Safari(JavaScriptCore)、Chrome(V8)、Opera(futhark)与IE(JScript)的行为是一致的。
另一方面Firefox(SpiderMonkey)和Rhino则会将with内(以及所有语句结构如if、for内的)的函数声明视作函数表达式处理。所以输出结果是:
ReferenceError: test is not defined
ReferenceError: test is not defined
C2
C2
因为本来就有分歧,所以我们不必要求let转换为with后的行为必须所有引擎一致。我们评判let转换为with后的行为是否合理,可以根据不同引擎的情况来分析。
首先在Mozilla一系的JS引擎中,将let语句转换为with语句,其内部函数声明的行为是相同的(即都视同函数表达式处理)。其次,虽然IE等引擎中并没有let语句,但我们可以认为let语句与for、if、with等语句是相似的结构,所以就let语句而言,可以预期IE等引擎下的let语句中包含函数声明的行为应该同转换为with语句后的行为一致。
至于let声明方面,假如这个let声明处于某个语句内(如if、for等结构),则情况与let语句是一样的。如果let声明不处于某个语句中,也就是直接在函数中,它就可以被安全的替换为var声明,而无需转换为with了。
最后总结一下,let结构如何转换为ES3中可以执行的代码:
1. let语句转换为with语句
转换为
2. let表达式转换为函数表达式
转换为
3. 语句block中的let声明转换为with语句
转换为
4. 函数中直接的let声明转换为var声明
转换为
以上。
没有转换的需求哪
普通来说是没有。
考虑这些个问题实际上是为写一个ES3.1到ES3的转换器/翻译器/预处理器做热身。
主要是在shcheme中,let本质上是个语法糖,而scheme是lexical scope。认真看了文章,我有个疑问,js引入let的动机是什么?
动机么,其实就是完善lexical scope,加入本来缺乏的block scope啊。大多数语言都支持block scope的,JS没有理由不支持。其实按说早该如此,只能怪BE当初偷懒了。。。
dennis_zane 写道转为函数表达式是正常的做法,因为let本质上就是语法糖。哎,咋看了我的文章之后还是这样认为呢?let并不仅仅是语法糖,而是要求对JS的语义进行增强。本文已经证明了不是所有的let结构都能被转换为function。不过在一定程度上,可以将let结构转换为with结构。不过,这只是将let语句合理转换到可以在ES3下运行的权宜之计,一个切实的JS引擎断断不可将let只实现为with和function的语法糖,而是应该真正实现block级别的scope。
我犯了主观臆断的错误,在js大家面前献丑了 。主要是在shcheme中,let本质上是个语法糖,而scheme是lexical scope。认真看了文章,我有个疑问,js引入let的动机是什么?
转为函数表达式是正常的做法,因为let本质上就是语法糖。
哎,咋看了我的文章之后还是这样认为呢?
let并不仅仅是语法糖,而是要求对JS的语义进行增强。
本文已经证明了不是所有的let结构都能被转换为function。
不过在一定程度上,可以将let结构转换为with结构。
不过,这只是将let语句合理转换到可以在ES3下运行的权宜之计,一个切实的JS引擎断断不可将let只实现为with和function的语法糖,而是应该真正实现block级别的scope。
本文所述的“with”转换方式存在一些缺点,请进一步阅读如何将let结构(block scope)转换到当前的JavaScript代码
以下是2008年11月的原文。
JavaScript 1.7开始加入了let结构。你可以在FF2以上开启let的支持:
<script type="application/javascript;version=1.7">...</script>
我们知道JS虽然是近似lexical scope,但是并非真正lex scope。其中一点就是ES3的spec所确定的scope chain机制,只作用到function这一层(虽然内部还有with和catch的特例),因此JS只有function scope而没有block scope。对于习惯block scope的程序员来说这带来一些微妙的bug隐患。比如:
var f = [] for (var i=0;i<10;i++) { var x = i * 100 f.push(function () {return x}) }
在for循环中的var x定义,并不会为每次循环产生一个不同的x引用,所有的x其实都是一个,就是在for循环所属的函数的scope下的唯一的那个x。因而如果你在每次循环中产生一个不同的闭包(比如为一系列元素设置事件处理器),并在闭包中引用了x的话,这个x并不会像程序员所期望的那样对应循环当时的x,所有的闭包中的x最后都指向到相同的那个x,当你运行闭包时,其值就必然是x在最后一次循环时所赋值(在上面这个例子中就是f[0]到f[9]的调用结果一律为900)。这种行为让许多程序员感到难以理解。
let的引入就是为了解决这个问题,甚至因此牺牲了向前兼容性,因为let是关键字,而老的程序可能用let作为变量名。为保持向前兼容性,导致你必须在script元素中明确声明version来启用let(以及其他无法向前兼容的)特性。
let的例子如下:
A. let语句:
var x = 5; var y = 0; let (x = x+10, y = 12) { print(x+y + "\n"); } print((x + y) + "\n");
B. let表达式
var x = 5; var y = 0; document.write( let(x = x + 10, y = 12) x+y + "<br>\n"); document.write(x+y + "<br>\n");
C. let定义
var f = [] for (var i=0;i<10;i++) { let x = i * 100 f.push(function () {return x}) }
A和B的输出结果都是27,5。
C和之前所举的例子完全一样,除了for内部从var x改为了let x。而此时f[0]()到f[9]()的调用结果就和我们期望的一样,为0,100,200直到900。
下面我来讨论一下,如何在现有的ES3的引擎中模拟let的行为。如果是手写代码,自然可以规避let的问题。不过这里讨论的是有没有可能找到一个模式可以套用,这样就可以将含有let结构的代码自动转换为可在现有ES3引擎中正确执行的代码。
A. let语句转换为一层function调用:
var x = 5; var y = 0; void function(x,y){ print(x+y + "\n"); }(x+10,12) print((x + y) + "\n");
B. let表达式转换为一层function调用:
var x = 5; var y = 0; document.write( function(x,y){return x+y}(x+10,12) + "<br>\n"); document.write(x+y + "<br>\n");
C. let定义转换为一层function调用:
var f = [] for (var i=0;i<10;i++) { void function(x){ x = i * 100 f.push(function () {return x}) }() }
这样看似就OK了。然而其实还有问题。比如,如果包含了this关键字呢?
function Test(x, y) { this.x = x; this.y = y } Test.prototype.run = function () { let (y = 12) { print(this.x+y + "\n"); } print((this.x + y) + "\n"); } new Test(5, 0).run()
如果依样画葫芦改为:
function Test(x, y) { this.x = x; this.y = y } Test.prototype.run = function () { void function(x) { print(x+this.y + "\n"); }(this.x+10) print((this.x + this.y) + "\n"); }
是不行的。
需要改为这样:
function Test(x, y) { this.x = x; this.y = y } Test.prototype.run = function () { (function(x) { print(x+this.y + "\n"); }).call(this, this.x+10) print((this.x + this.y) + "\n"); }
但是这也不解决所有问题,如果是夹杂控制跳转语句的话怎么办?
比如
function test(n) { for (var i = 0; i < n; i++) { let (x = i * i, y = i + 20) { if (x < y) continue else if (x == y) print(x) else break } } }
在scope中如果存在跳转到block之外的语句,那直接套用一层函数是不行的。
一种解决方法是,让函数返回特定值,然后处理之。如:
function test(n) { for (var i = 0; i < n; i++) { var CONTINUE = {}, BREAK = {} var _result = function(x, y) { if (x < y) return CONTINUE else if (x == y) print(x) else return BREAK }(i * i, i + 20) if (_result === CONTINUE) continue; else if (_result === BREAK) break; } }
然而,这种方法较为复杂,需要处理continue、break、return和throw语句,尤其是多层嵌套和带有label的跳转,需要识别出哪些语句是跳转到本block之外,并只对这些语句进行转换。为此必须对程序进行完整的解析。
有没有更轻便的方法?
这本来是mission impossible,然而JS的lexical scope留了个后门,那就是with。with可以在现有的scope chain头上附加一层binding。有了with我们不难得到A和C的等价形式(B是let表达式,还是转换为function更方便):
A. let语句转换为with:
var x = 5; var y = 0; with ({x:x+10, y:12}) { print(x+y + "\n"); } print((x + y) + "\n");
C. let定义转换为with:
var f = [] for (var i=0;i<10;i++) { with ({x:undefined}) { x = i * 100 f.push(function () {return x}) } }
容易看出,改为with结构没有this引用的问题。更重要的是with只是一个statement,其中的continue、break、return、throw语句一律不会受到影响。
不过事情没有完美的。with的问题是,按照ES3规范来说,with语句中(if语句、for语句等)是不能有function声明的(但是允许function表达式)。不过如果你这样干了,现有的JS引擎大多并不会报错,但是在行为上有所差异。
var x = 'A' void function () { var x = 'B1' try { test() } catch(e) { say(e) } with ({x:'C1'}) { try { test() } catch(e) { say(e) } x = 'C2' function test() { say(x) } test() } x = 'B2' test() }() function say(s) { alert(s) }
在IE(JScript)中,with对函数声明的scope不会有影响,所以输出结果为:
B1
B1
B1
B2
Safari(JavaScriptCore)、Chrome(V8)、Opera(futhark)与IE(JScript)的行为是一致的。
另一方面Firefox(SpiderMonkey)和Rhino则会将with内(以及所有语句结构如if、for内的)的函数声明视作函数表达式处理。所以输出结果是:
ReferenceError: test is not defined
ReferenceError: test is not defined
C2
C2
因为本来就有分歧,所以我们不必要求let转换为with后的行为必须所有引擎一致。我们评判let转换为with后的行为是否合理,可以根据不同引擎的情况来分析。
首先在Mozilla一系的JS引擎中,将let语句转换为with语句,其内部函数声明的行为是相同的(即都视同函数表达式处理)。其次,虽然IE等引擎中并没有let语句,但我们可以认为let语句与for、if、with等语句是相似的结构,所以就let语句而言,可以预期IE等引擎下的let语句中包含函数声明的行为应该同转换为with语句后的行为一致。
至于let声明方面,假如这个let声明处于某个语句内(如if、for等结构),则情况与let语句是一样的。如果let声明不处于某个语句中,也就是直接在函数中,它就可以被安全的替换为var声明,而无需转换为with了。
最后总结一下,let结构如何转换为ES3中可以执行的代码:
1. let语句转换为with语句
let (n1=exp1,n2=exp2,...) { ... }
转换为
with ({n1:exp1,n2:exp2,...}) { ... }
2. let表达式转换为函数表达式
let (n1=exp1,n2=exp2,...) exp
转换为
(function(n1,n2,...){return exp}).call(this,exp1,exp2,...)
3. 语句block中的let声明转换为with语句
statement { ... let n1 = exp1 ... let n2 = exp2 ... let n3 = exp3, n4 = exp4, ... ... }
转换为
statement { with ({n1:undefined,n2:undefined,n3:undefined,n4:undefined,...}) { ... n1 = exp1 ... n2 = exp2 ... n3 = exp3; n4 = exp4; ... // 注意这里“,”要变成“;” ... } }
4. 函数中直接的let声明转换为var声明
function ...() { ... let n1 = exp1 ... let n2 = exp2 ... let n3 = exp3, n4 = exp4, ... ... }
转换为
function ...() { ... var n1 = exp1 ... var n2 = exp2 ... var n3 = exp3, n4 = exp4, ... ... }
以上。
评论
8 楼
hax
2008-12-09
搞不懂本文为什么有那么多人踩。。。
巧合的是,Yahoo的尼古拉斯·西·扎卡斯(名咋那像恐怖分子涅)同学这两天也提到了block level的问题:[url]
http://www.nczonline.net/blog/2008/12/04/javascript-block-level-variables/[/url]
巧合的是,Yahoo的尼古拉斯·西·扎卡斯(名咋那像恐怖分子涅)同学这两天也提到了block level的问题:[url]
http://www.nczonline.net/blog/2008/12/04/javascript-block-level-variables/[/url]
7 楼
vb2005xu
2008-11-26
我的IAMSESEJS什么时候可以出头啊!!!!
6 楼
hax
2008-11-26
fregen 写道
没有转换的需求哪
普通来说是没有。
考虑这些个问题实际上是为写一个ES3.1到ES3的转换器/翻译器/预处理器做热身。
5 楼
fregen
2008-11-26
没有转换的需求哪
4 楼
hax
2008-11-25
dennis_zane 写道
主要是在shcheme中,let本质上是个语法糖,而scheme是lexical scope。认真看了文章,我有个疑问,js引入let的动机是什么?
动机么,其实就是完善lexical scope,加入本来缺乏的block scope啊。大多数语言都支持block scope的,JS没有理由不支持。其实按说早该如此,只能怪BE当初偷懒了。。。
3 楼
dennis_zane
2008-11-25
hax 写道
dennis_zane 写道转为函数表达式是正常的做法,因为let本质上就是语法糖。哎,咋看了我的文章之后还是这样认为呢?let并不仅仅是语法糖,而是要求对JS的语义进行增强。本文已经证明了不是所有的let结构都能被转换为function。不过在一定程度上,可以将let结构转换为with结构。不过,这只是将let语句合理转换到可以在ES3下运行的权宜之计,一个切实的JS引擎断断不可将let只实现为with和function的语法糖,而是应该真正实现block级别的scope。
我犯了主观臆断的错误,在js大家面前献丑了 。主要是在shcheme中,let本质上是个语法糖,而scheme是lexical scope。认真看了文章,我有个疑问,js引入let的动机是什么?
2 楼
hax
2008-11-25
dennis_zane 写道
转为函数表达式是正常的做法,因为let本质上就是语法糖。
哎,咋看了我的文章之后还是这样认为呢?
let并不仅仅是语法糖,而是要求对JS的语义进行增强。
本文已经证明了不是所有的let结构都能被转换为function。
不过在一定程度上,可以将let结构转换为with结构。
不过,这只是将let语句合理转换到可以在ES3下运行的权宜之计,一个切实的JS引擎断断不可将let只实现为with和function的语法糖,而是应该真正实现block级别的scope。
1 楼
dennis_zane
2008-11-25
转为函数表达式是正常的做法,因为let本质上就是语法糖。
发表评论
-
论ES6模块系统的静态解析
2013-03-14 04:56 15875本文是Dave Herman的《Stati ... -
如何创建一个JavaScript裸对象
2012-08-27 02:11 8050所谓裸对象,即 naked object ,是指没有原型(sp ... -
JavaScript语句后应该加分号么?
2012-06-19 03:10 14380这是一个老生常谈的问 ... -
shim是应该抛异常还是应该fail silently?
2011-08-11 17:26 5581玉伯发布了es5-safe模块 ... -
7月30日的广州演讲视频和Slides
2011-08-01 23:38 31757月30日在W3CTech广州站活动上的演讲,题目是:ECMA ... -
如何判断一个函数的意图是被用作构造器,也就是可视为“类”
2011-07-21 13:55 2948前提是不要求做什么特殊标记。只是最大可能的猜测函数的作用大概是 ... -
关于国内前端和JS技术发展的乱想
2011-07-19 18:53 33267玉伯在我的一条微博后面写了一些(和主题不是很相关但)非常值得思 ... -
Module与Trait的比较
2011-08-12 12:50 4004最近我多次提及module和trait。 粗看,我们可以发现 ... -
如何将let结构(block scope)转换到当前的JavaScript代码
2011-07-12 17:24 3009本文是对如何将let结构转换到ES3代码的补充。 首先,原文 ... -
JavaScript的未来方向之观察
2011-07-12 02:53 8373最近每次去杭州,都有 ... -
我为什么力挺NodeJS
2011-07-04 00:27 0之前在参加CNodeJS社区在 ... -
JS之父再谈JS历史(续完)
2010-12-31 04:20 3439又到年底,我觉得是时候还债了。自开blog来,我出了不少“太监 ... -
我为什么是DC黑续,兼答Tin
2010-04-27 14:29 0我同意安全是一个重要问题。我不同意的是把所谓安全放到凌驾于其他 ... -
我为什么是DC黑─Why I disagree with Douglas Crockford
2010-04-26 17:51 11016参加完了QCon北京大会, ... -
写对正则:一行代码,速度差50倍
2009-05-12 03:43 60132009-05-11 A lesson of ... -
JavaScript的EOS(分号)问题
2009-05-08 16:24 5779在http://bbs.51js.com/viewthre ... -
JavaScript五大关键字
2009-05-06 17:53 4768近期做语法高亮项目的副产品,是统计了一下几个主流JS工具包中各 ... -
curry和partial的差别
2009-03-28 00:15 371451js上asfman翻译了http://ejohn.org/ ... -
Eval is Evil , With evil too
2009-03-27 18:39 0with的问题: 2009-3-27 17:12:40 ... -
IE全局变量的Dissociative Identity Disorder(人格分裂症)
2009-03-16 02:47 14736最近,小麦提出了一个疑惑: 小麦 写道最后介绍一个我也搞不明白 ...
相关推荐
这样的工具可能是为了帮助开发者将现代JavaScript语法转换为ES3,以便在那些不支持新特性的老旧浏览器上运行。这种转换过程称为“转译”或“编译”,常见的工具有Babel等。 EasySysprep_3.1Final可能是这个封装工具...
Babel预设,用于将ES2015和现代JS约定转换为ES3。 旨在与Extendscript一起使用。 安装 使用NPM: $ npm install --save-dev babel-preset-extendscript 使用纱线: $ yarn add --dev babel-preset-extendscript ...
2. **双击导入.reg**:这通常是一个注册表文件,用户双击后可以将其内容导入到系统的注册表中,可能是为了配置工具或优化系统设置。 3. **Hnwglm.cn说明.txt**:这是一个中文说明文件,可能包含了关于如何使用ES3RC...
`eslint-config-medikoo-es3`就是针对这些项目而设计的,确保它们也能享受到ESLint带来的代码质量保障。 ### opinonated配置 "Opinionated"在这里意味着这套配置具有强烈的主观倾向,它遵循一套预设的编码风格和...
1. **兼容性广泛**:由于"ES3系统封装工具"特别强调支持全部Windows系列,这意味着它可以处理从Windows XP到最新的Windows 10等不同版本的操作系统,满足了企业内部可能存在的多样化操作系统需求。 2. **傻瓜化操作...
5. **扩展能力**:手册会说明DVP-ES3系列的扩展能力,包括最大扩展模块点数、机种代码以及脉冲输出自动复位功能。 6. **服务支持**:中达电通提供的全方位服务也是手册的一部分,包括70多个分支机构和技术团队的...
let-er, Transpile非ES6允许块进入 ES6 ( 或者 ES3 ) ES6正在把 let x ="foo" JavaScript的语法,它基本上劫持任何 block 并将你的声明扩展到 block ( 而不是像ES5和 below 那样提升到包含函数) 。然而,有问题:ES6...
Kotlin与JavaScript有很好的互操作性,可以通过Kotlin的JS编译器将Kotlin代码编译成JavaScript,因此可能与ES3有一定的关联。 在压缩包文件名称"es3-master"中,"master"通常代表这是一个项目的主分支,可能是某个...
ES3A THRU ES3J SMAF YONGYUTAI
技嘉主板P43-ES3G最新官方2010/02/09版bios。增强内存处理速度
技嘉EP43T刷码用bios.rom (GA-P43-ES3G rev1.0 F13)
有所帮助,但无法转换node_modules中的模块。 所以我写了一个简单的插件来解决它。 希望它能对您有所帮助。 用法 npm install es3ify-webpack-plugin --save-dev 然后在webpack.config.js中 var es3ifyPlugin = ...
台达PLC_DVP-ES3系列是一款由台达电子科技公司推出的可编程逻辑控制器,其硬件配置丰富,适用于各种工业自动化应用场景。本手册详细介绍了该系列PLC的硬件配置、连线设定、主机运作以及软件设定等内容,旨在帮助用户...
将 ES6 其余参数转换为 ES3: var join = function ( joinStr , ... items ) { return items . join ( joinStr ) ;} ; 变成: var join = function ( joinStr ) { var items = [ ] . slice . call ( arguments , 1 )...
Easy Sysprep v3 beta 3.0是一款采用向导模式的自动化封装工具,有效地将封装步骤明确化、将各类设定规则化。保证新手能更快上手并明白封装要做什么,让老手更方便各类操作,不至于遗漏操作,可以说是真正的傻瓜式...
这通常意味着开发者可以将这套配置导入到他们的项目中,从而确保代码风格的一致性,提高代码质量和可读性。Eslint-config-medikoo-es3可能包含了一些针对ES3特性的特定规则,以便在旧代码库中更有效地工作。 **标签...
### GLSL ES3官方文档知识点解析 #### 一、概述 **GLSL ES3**(OpenGL ES Shading Language Version 3.00)是专为...对于开发者而言,深入理解GLSL ES3的特性和使用方法,将有助于他们创建出更高质量的移动应用程序。
DSDT(P43-ES3G F14).aml
SaveFile.es3