w3ctech 2011 JavaScript 专题会议(广州站)​综述

阅读数:297 2011 年 8 月 8 日 23:54

w3ctech 2011 JavaScript 专题会议(广州站)​日前在华师大附中召开,参会者近 300 人,来自国内技术社区的四位知名专家陈广琛、赵劼、周爱民、贺师俊分别做了精彩的演讲,涉及的内容包括​​​​云端 NodeJS、JS 异步解决方案 Jscex、开源 Javascript 引擎 Narcissus、ECMAScript 5 的 strict 模式等。InfoQ 中文站整理了大会的精彩内容,供读者参考。

云端 JavaScript 漫游指南

雅虎前端工程师陈广琛演讲的主题是《云端JavaScript 漫游指南》​,他以丰富的实例和现场演示介绍了 NodeJS 的强大功能和云端部署的​知识。

正如陈广琛在开场白里所说,十年前的 Javascript 还要看 VBScript、PHP、CGI 的脸色,而如今 Javascript 的强大从前端延伸到了后端。在​解释 JavsScript 依靠 NodeJS 平台作为服务器端编程语言​的优势时​,他在会场演示了两个功能不大但让人印象深刻的 NodeJS 开发案例,这些以前 Web 开发人员需要采用其他语言实现的功能,如今用熟悉的 JavaScript 即可完成。让我们来体会一下 NodeJS 的魅力。

域名重定向(biz-to-me)代码示例​:

 const http = require('http');

 var server = http.createServer(function(request, response) {

    var host = request.headers['host'];

    var url = request.url; 

    console.log('request from: http://' + host + url);



    host = host.replace(/catchen\.biz$/, 'catchen.me');

    if (host == request.headers['host']) {

        host = 'catchen.me';

        url = '/'

    }

    var location = 'http://' + host + url;



    console.log('redirect to: ' + location);

    response.writeHead(302, {

        Location: location

    });

    response.write('Temporarily moved to <a href="' + location + '">' + location + '</a>.');



    response.end();

});

var port = process.env.PORT || 3000;

server.listen(port, function(){



    console.log("Listening on " + port);

});

​短 URL 解析(traceurl)的代码示例可以从这里查看。

从这两个例子中,我们可以看到一些亮点,比如:

  • 导入函数库时,可以赋值给命名常量,便于范围管理,像 const http = require('http')。
  • 服务器端处理主要函数是 createServer 中传入的回调函数 function(request, response)。
  • 从 request 解析 http 请求,用 response 返回响应。
  • 采用 Javascript 语言,参数 Json 风格。
  • 无需配置 Apache。
  • 支持 URL 路由(字符串定义和正则表达式两种)。

陈广琛特别介绍了 NodeJS 的 Express.js 库,常用的功能包括:

  • 日志管理
  • 路由
  • cookie 解析
  • session 管理
  • 模板引擎

有志于从事 NodeJS 应用开发的朋友,可能会担心 NodeJS 相关的支持工具包(package)不够多从而导致开发比较麻烦。陈广琛建议大家利用 NPM 搜索已有的工具包。NPM 是针对 NodeJS 的包管理器,可以用来安装和发布 NodeJS 应用,它能够管理依赖等。除了利用第三方的工具包,陈广琛还介绍了如何构建自己的 package(见短 URL 解析代码示例),大体分为三步:

  • 使用 module.exports 编写模块。
  • 提供 package.json 和 index.js 文件。
  • 使用 npm publish 发布。

演讲的后半部分转到了演讲的关键字——云端。对于已经构建好的 NodeJS 应用,部署在何处?陈广琛指出,无论是租用机房的服务器还是购买 VPS 服务,都不是理想的选择,“云端”才是大势所趋。他介绍了四款 NodeJS 云端服务:

其中 Heroku 提供每月 750 小时的单进程免费服务,适合于简单的 NodeJS 应用和学习实践。

最后,陈广琛指出 NodeJS 的最大优势在于高并发和异步 IO,只有应用存在这些需求时,NodeJS 才会表现出相比其他平台或语言的过人之处。

提升 JavaScript 生产力的“异样”编程手段

IBM 高级咨询师、InfoQ 中文站编辑赵劼以《提升JavaScript 生产力的“异样”编程手段》为题介绍了其创建的Javascript 开源项目 Jscex ,对深陷异步编程困扰的开发人员很有启发和帮助。

老赵在开场阶段一如既往地批评 Java 语言的不足,他以构建书籍索引为例,C#语言的实现代码如下:

// C#

List<string> keywords = ...;

var result = keywords

    .GroupBy(k => k[0].ToUpper())

    .ToDictionary(

        g => g.Key,

        g => g.OrderBy(k => k).ToList());

与此形成鲜明对比的是 Java 语言的实现代码:

List<String> keywords = ...;

Map<Character, List<String>> result = new HashMap<...>();

for (String k: keywords) {

    char firstChar = k.charAt(0);

    if (!result.containsKey(firstChar)) {

        result.put(firstChar, new ArrayList<String>());

    }

    result.get(firstChar).add(k);

}

for (List<String> list: result.values()) {

    Collections.sort(list);

}

老赵总结了 Java 的四点不足:

  • 命令式编程(强调怎么做)
  • 复杂的匿名类型语法
  • 强制写清所有类型名
  • 无法扩展既有类型

而现代语言的常见特性是什么呢?

  • 声明式编程(做什么)
  • 易用的 Lambda 表达式语法
  • 类型推断(对于静态语言)
  • 无侵入的类型扩展

老赵指出,Javascript 有着优秀的特性,不过在异步编程时存在不足,会破坏代码局部性,将逻辑拆分地支离破碎,同时对异步操作之间的协作和组合、异常处理及取消造成了困难,开源项目 Jscex(JavaScript Computation EXpression)正是为了解决这些问题,其借鉴了 F#的计算表达式特性,Jscex 是 Javascript 语言扩展,通过非常巧妙的手段让开发人员享受异步编程的乐趣。比如,在定义异步操作时,需要采用如下代码形式:

// 使用异步构造器执行编译后的代码

var somethingAsync = eval(Jscex.compile("async",

    function (...) {

        // 实现

    }

));

调用形式如下:

function () {

    var res = $await(<async work>);

}

适用的异步任务包括:HTTP 请求、UI 事件、时钟回调、查询响应、Web Service 响应、代理消息等。这种编程方式使得开发人员在异步处理时不会被无处不在的 SetTimeout() 函数困扰,确保代码结构清晰、便于维护。

老赵特别介绍了其 Jsces 编译器所采用的核心思想和技术:

  • 视 JavaScript 代码为 DSL
  • 使用函数的 toString 方法获得代码
  • 使用 eval 动态执行代码

关键思路可以概括为:

var compile = function (f) {

    // 获得函数代码

    var code = f.toString();

    // 解析代码至语法树

    var ast = parse(code);

    // 生成新代码

    return generateCode(ast);

}

其优点包括:

  • 载体即为普通 JS 代码,行为一致
  • 无需额外编译步骤
  • 可以使用原有 JavaScript 编辑环境

针对 eval 的性能和安全问题,老赵指出 JScex 支持在发布前生成编译后的代码,去除 eval 和 compile 的开销,解除与编译器的依赖。

目前社区中存在多种异步框架和异步语言,老赵在对比分析时表示,Jscex 的优势在于:

  • 使用 JavaScript 表达逻辑
  • 极高的灵活度和表达能力
  • 只需少量学习
  • 完全使用 JavaScript 语法
  • 完全保留 JavaScript 语义
  • 完全保留 JavaScript 编程体验

Jscex 基于 BSD 协议开源,目前托管于 github sndacode 上。感兴趣的读者朋友可以阅读老赵为 InfoQ 中文站独家撰写的深度技术文章《使用Jscex 改善JavaScript 异步编程体验》。

JS in JS——在 JS 中实现 JS 引擎的详细剖析

资深技术专家、支付宝架构师周爱民分享了Mozilla 开源Javascript 引擎 Narcissus (采用 Javascript 实现)在语法分析、语句执行方面的技术细节,让到场的开发人员对 Javascript 有了更深的理解。

周爱民首先抛出了三个例子,让大家判断一下运行结果分别是什么(读者可以尝试一下):

function() {

}()

function() {

}(1)

(function() {

})(1)

在强调了理解 Javascript 语法的重要性之后,周爱民介绍了 Narcissus 项目的基本情况,它由 js.js、jsdefs.js、jsparse.js 和 jsexec.js 四个文件组成。其中重点是后两个文件。jsparse.js 主要用于语法分析。在 Narcissus 中,语法层次由高到低分为 Script、Statements、Statement、ParenExpression、Expression 等,都视为 Node。以 var a, i = 100 , v = i + 100; 为例,其语法树为:

jsexec.js 文件主要包含了语句执行的引擎代码,周爱民介绍了 Javascript 语言上下文执行环境、new、with、function、object、eval 等重要概念、技术的实现细节和对开发者的启示。以 new 为例,其中的关键代码如下:

v = f.__construct__(a, x);

……

FOp.__construct__ = function(a,x) {

  var o = {}, p = this.prototype;

  o.__proto__ = p;

  var v = this.__call__(o, a, x);

  if (isObject(v)) return v;

  return o; 

周爱民建议大家认真读一下 Narcissus 项目的源代码,有助于体会 Javascript 的精髓。jsparse.js 和 jsexec.js 两个文件的代码都在 1000 行左右,感兴趣的读者可以结合周爱民的视频学习 Narcissus 项目,这是一个很好的起点。 

ECMAScript 5——Improve the Safety of JavaScript

盛大创新院研究员贺师俊在第四场演讲中以ECMAScript 5 为主题精彩收尾。他首先指出了ECMAScript 的发展方向,包括:

  • API 扩展和标准化:JSON、Array.protoype.forEach/map/filter...
  • 通用化,可实现平台对象:get/set accessor、Object.defineProperty 等等
  • 适应于 PITL(programming-in-the-large)

他认为 Javascript 传统上是小型开发语言,存在一些不足:

  • 设计为一门依赖于 host 环境的脚本语言
  • 无内置 module/namespace
  • 缺少较全面的标准 API 库
  • 缺乏各种 invariants 约束的能力
  • 残缺的 OO

正式因为存在这些缺陷,导致开发人员在使用 Javascript 编程时,经常掉进危险的陷阱。贺师俊结合日常工作中的亲身实践列举了几个,包括 this 引用、with 语句等,都会引起潜在的代码漏洞,在企业级开发中,由于代码结构比较复杂,使得开发人员在调试 bug 时难以定位。比如下面这个小例子:

Dog.prototype.setName = function(name) {

    this.name = String(name).toLowerCase()

}

贺师俊认为 String(name) 并不是一种鲁棒性的实践方式,反而可能在开发人员的不经意间导致代码的错误而且不易发现,比如:

var q = new Dog()

q.setName(q)    // q.setName('q')

如何解决这些问题呢?贺师俊建议开发人员在条件允许的情况下开启 ECMAScript 5 的 strict 模式,并应用一些辅助开发工具包,例如 guard.js jsguards jsHelpers Overload Trademark/Guard proposal 等。 

没有参会的朋友可以通过主办方 w3ctech 的相关页面下载幻灯片和观看演讲视频。JavaScript 专题会议北京站和上海站分别将在 8 月 27 日和 9 月 24 日举行,感兴趣的读者可以报名(北京)和预约(上海)参加。InfoQ 中文站将继续关注国内 Web 技术社区的发展。

评论

发布