Meet JS

· 862 words · 2 minute read

这两天修复了一个前同事遗留下来的bug,也因此(几乎)首次接触了JavaScript以及 WebUI 方面的东西。我一直避免接触任何 UI 相关的事情, 因为总觉得其某些方面太过琐碎,容易分心。不像算法、或者编程范式、模型那样比较具有通用性。

由于专门学习过 Scheme, OCaml 以及 F# 等函数式语言,因此 JS 用起来还算顺手。但是其变量的作用域是函数作用域(function scope)而不是块作用域(block scope),有点意外1。比如,下面这段代码的会打印出1来。

var f = function() {
    if (true) {
        var a = 1;
    }
    return a;
}

console.log(f())

发现bug时,稍微研究过同事的代码,知道出问题的地方在哪里,但是当时不知道怎么改。探索过程:

  1. 安装了node.js2,方便编译、调试 - 因为我比较习惯在终端下工作;
  2. 用 golang 写了一个简单的测试用 Web API;

这样我就可以非常方便的测试 js 代码。因为 AJAX (POST) 默认不能跨域,所以用测试程序和 golang 写的 API 在一台机器上。现有的实现中,AJAX 调用需要同步执行 (async: false),我只能保持该行为。由于需要改为调用多次, 发现如下行为:

  1. 循环中调用 AJAX 会导致 JsCop 报错 - 不允许在循环中调用函数。绕过的办法是用 jquery 中的 $.each
  2. 如果用 $.when.apply 去求值一个 AJAX 调用的数组时,async 指定为false 会出错。具体原因有待分析,有的说可能是 jquery 的问题。但语义上确实也有点别扭。

修改了 js 后,需要有一个 handler 在某个下拉框的选值变动时,去自动更新另外一个下拉框的内容。在同事二雪的帮助下弄出来一个可以工作的版本,但是自我感觉不简洁。后来在原开发者的帮助下只用一行搞定了。

最后还是要感谢一下麻麻,作为资深 Web 开发者,一眼就看出我之前调试的时候遇到的一个困惑:浏览器加载的js文件不是我改动后的。因为我没有刷新

教训:还是老话,It is not my fault doesn't mean it is not my problem. 最近在读的《The Clean Coder》里面讲到很多态度问题,获益良多。


  1. 题外话,Emacs Lisp 是 dynamic scoping 而不是 lexcial scoping。 ↩︎

  2. 发现某些版本下 node.js 里面用 jquery 有点问题,大概原因是新的 jquery 里面依赖新的 jsdom,而 jsdom 只支持 io.js。解决的办法是安装了一个旧版本 npm install jquery@1.8.3 ↩︎

js
comments powered by Disqus