www.zhblog.net

从 ECMAScript 5 开始


ECMAScript 6 都已经正式释出两年了,才来从 ECMAScript 5 开始?其实也是因为这样,还有那样的原因,我有必要重新看一下 JavaScript 的东西,只是看有点无聊,想说就干脆来改版好了… XD

不少长青(Even-green)浏览器在 ES6 的支持度上已经不错了,然而为了兼容性,不少程序库或既有应用程序,都还不是 ECMAScript 6 写的,那么至少,从 ECMAScript 5 严格模式比较好,更旧的写法我就不再提了。

如果打算把应用程序从旧旧的 JavaScript 升至 ECMAScript 6,先想办法整理代码,使之能在 ECMAScript 5 严格模式下存活,会是比较渐进的作法;就算想用 ECMAScript 6 重写应用程序,然而基于兼容性,使用了工具将 ECMAScript 6 转换为旧版的 JavaScript,总是有时会需要看懂转换出来的代码吧!

因此,接下来会先以〈JavaScript 语言核心〉为基础进行修改,忽略那些严格模式下无法使用的语法元素,在 ECMAScript 5 重新整理完过后,希望能开始聊聊 ECMAScript 6,然后将〈JavaScript 本质部份〉中,浏览器部份的文件也用 ECMAScript 6 更新一下,并将旧版 IE 的说明剔除 … 呃… 这会是一条漫长的路(想到就蛮累的,总之慢慢来吧! … XD)。

那么,就语言的部份,还是使用 Node.js 来作为示范平台吧!(虽然 JDK9 附的jjs也支持不少 ES6 特性了,不过不知道支持到什么程度就是了)就写这篇文件的时间点上,我使用的是 8.9.1 LTS 的 Windows 版本。

C:\workspace>node -v
v8.9.1

只输入node会进入指令互动环境,按下 Ctrl+D 可以离开,如果要将代码写在 .js 里头再执行,例如编辑一个 helloworld.js:

console.log('Hello, World');

然后执行node helloworld.js就可以执行程序:

C:\workspace>node helloworld.js
Hello, World

如果需要在执行时给定命令行实参的话,可以使用process.argv,这是一个数组(Array实例),索引 0 是'node'指令名称,索引 1 是你的 .js 文件路径,如果有指定实参的话,这些实参会是从索引 2 开始存储。例如若你的 helloworld.js 是:

process.argv.forEach(function(arg, index) {
    console.log(arg + ', ' + index);
});

那么指定实参时,就会有以下的执行结果:

C:\workspace>node helloworld.js arg1 arg2
C:\Program Files\nodejs\node.exe, 0
C:\workspace\helloworld.js, 1
arg1, 2
arg2, 3

你发现了,我使用的是 Windows 版本上的,就学习语言而言,Windows 版本基本上应该是没问题。通常,我不太需要指令名称与文件路径,因此,可以只撷取之后索引 1 之后的实参:

var args = process.argv.slice(2);
console.log('Hello, ' + args[0]);

这样的话,就可以透过args索引 0 开始来获取 .js 文件名称之后供给的命令行实参了:

C:\workspace>node helloworld.js Justin
Hello, Justin

ECMAScript 5 的严格模式(strict mode),这只要在你想要的代码范畴中,加入一段use strict字符串,如果有支持严格模式的环境就会采纳,没有支持的环境,只是当作一个平凡的字符串罢了。

例如,在 ES5 的严格模式下,不允许对未使用var定义的变量指定值:

'use strict';

x = 10;
console.log(x);

使用 Node.js 的话,执行以上 .js 文件,将会发生错误:

C:\workspace>node helloworld.js
C:\workspace\helloworld.js:4
    x = 10;
      ^

ReferenceError: x is not defined
    at Object.<anonymous> (C:\workspace\helloworld.js:4:7)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Function.Module.runMain (module.js:676:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3

也可以在使用node指令时,加上--use_strict,例如:

C:\workspace>node --use_strict
> x = 10;
ReferenceError: x is not defined
    at repl:1:3
    at ContextifyScript.Script.runInThisContext (vm.js:50:33)
    at REPLServer.defaultEval (repl.js:240:29)
    at bound (domain.js:301:14)
    at REPLServer.runBound [as eval] (domain.js:314:12)
    at REPLServer.onLine (repl.js:441:10)
    at emitOne (events.js:121:20)
    at REPLServer.emit (events.js:211:7)
    at REPLServer.Interface._onLine (readline.js:282:10)
    at REPLServer.Interface._line (readline.js:631:8)
>

必须先声明的是,这系列不是 JavaScript/ECMAScript 语言入门,我只会写些语言中我觉得有兴趣的特性,因此,虽然从 ES7 开始,ECMAScript 打算采频繁的方式,持续每年释出新版本,内容包含当年已完成的新特性就好,不过,我目前的规划是不打算跟着这样 ES7、ES8 写下去,而这系列也不会是 Node.js 的介绍,方才一连串的简介,只是为了后续介绍语言核心时的必要准备。


展开阅读全文

评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 心情