Google 发布 Closure Linter

Google 很重视代码风格的一致性,而且还公开过一份 JavaScript 代码风格指南: Google JavaScript Style Guide,现在它们又发布了一个工具来帮助你检查 JavaScript 代码是否严格遵循了 Google JavaScript Style Guide :Closure Linter

假设你有以下代码:

var x = 10
var y=20;
 
for(var i = 0;i < 10; i++ ) {
  x += i;
   y -= i;
}
 
var z = [10, 20,];
 
x = y + z[0]
    + 10;

在命令行下运行 gjslint –strict fixme.js 之后,就会出现下面的结果:

Line 1, E:0010: (New error) Missing semicolon at end of line
Line 2, E:0002: Missing space before "="
Line 2, E:0002: Missing space after "="
Line 4, E:0002: Missing space before "("
Line 4, E:0002: Missing space after ";" in for statement
Line 4, E:0001: Extra space before ")"
Line 6, E:0006: (New error) Wrong indentation: expected any of {2} but got 3
Line 9, E:0121: Illegal comma at end of array literal
Line 12, E:0120: Binary operator should go on previous line "+"
Found 9 errors, including 2 new errors, in 1 files (0 files OK).

这个工具甚至可以帮你自动修复一些错误,运行 fixjsstyle –strict fixme.js 即可。(注意:不一定可以修复全部错误)

Closure Linter 支持 Windows, Linux & Mac OS X. 具体使用方法请看这里

两行 JavaScript 代码

最近看到了两行 JavaScript 代码,很受启发。

1. 封装 DOM 属性

在 JavaScript 中,我们可以获取HTML元素的属性值,例如 element.id 。但是,因为 for 和 class 是 JavaScript 中的关键字,所以在 JavaScript 中这两个属性名称分别用 htmlFor 和 className 代替,于是在封装的时候需要先对这两个属性进行特殊判断。通常,我们会这么写:

function getAttr(el, attrName){
var attr;
if ('for' == attrName) {
attr = 'htmlFor';
} else if ('class' == attrName) {
attr = 'className';
} else {
attr = attrName;
}
}

但是我在精通 JavaScript 发现了一种很妙的写法, John Resig 是这么写的:

function getAttr(el, attrName){
var attr = {'for':'htmlFor', 'class':'className'}[attrName] || attrName;
}

构建了一个对象来做判断,实在是巧妙!这样一来节省了很多代码,也就减少了BUG出现的可能性,而且也没有丧失其可读性,是很值得学习的。

2. 交换两个变量的值

这个问题相信学过一点编程的人都知道,一般来说我们会这么写:

var foo = 1;
var bar = 2;
 
var temp = foo;
foo = bar;
bar = temp;

通过一个临时变量来做数据的缓冲,很直观。但是否可以不使用临时变量呢?看一下下面的这行代码:

foo = [bar, bar=foo][0];

没有使用到临时变量,而是利用了数组。实在是妙!

上面这两行代码看上去很简单,不像一些诸如高级算法之类的代码那么显眼,但是,如果不是对语言本身非常了解,如果没有多年的编程经验和思考,如果对数据结构不熟悉,绝对不可能写出这样的代码。或许这种对每一行代码的深思熟虑,正是大师和平庸程序员之间的区别所在。

另外,这也从侧面说明了:编程的时候不要忘记思考,否则你就只是一个完成工作的机器。所以,如果你现在的工作只是让你疯狂做业务而不给你思考和学习的时间,别犹豫,换一个。

UPDATE:
首先感谢大家的热烈讨论。看了大家的讨论之后,我觉得要做一个说明。

这篇日志里面举的第二个例子和第一个例子放在一起确实有欠妥当,因为第二个例子只是一个“妙”字,在可读性方面确实没什么可取之处,只考虑这一方面,这种代码就不推荐在工作中写。

关于效率问题,使用临时变量和构建一个临时数组都是分配一块内存把数据放进去,它们之间的效率差别就是在构建数组的过程,而构建数组的效率是因浏览器引擎而异的,比如说在很多浏览器下面,数组声明使用 var a = [] 要比 var a = new Array 效率高,在有些浏览器下差别就不大,但可以肯定的是,构建数组肯定比单值变量耗时,效率方面这行代码也不行。虽然 jay.li 同学说的很对,“测试结果受浏览器类型和硬件影响,衡量操作速度的硬指标是‘算法时间复杂度’和‘空间复杂度’”,不过在实际工作中来说,尽管可能两种写法的复杂度都是 O(1),但是 1s 和 1000s 的差别我们还是要计较的。

关于 Y.Boy 同学所说的变量声明周期问题,既然你说“函数体内的局部变量在函数执行完后,就会被销毁”,那么为什么下面这段代码可以工作呢:

function example(arg1){
  var localVar = 2;
  return function inner(arg2){
    return arg1+localVar + arg2;
  }
}
 
var result = example(3);
var sum = result(4); // sum = 9;

最后,多谢 jay.li 同学提醒有关堆栈、scopChain这些概念,我要好好补习一下基础了。

推荐一本好书:计算机程序的构造和解释(SICP)

这几天想了解一下 LISP 语言,于是找了一大堆资料,其中就有这本《计算机程序的构造和解释》。刚开始的时候我并不知道这本书多么有名,但看了序言之后我立刻被这本书吸引住了,并断定这是一本好书。这本书如何经典大家可以自己去搜索一下,简介我就不放上来了,这里只摘抄一些序言中的一些段落,有兴趣的可以看一下。相信如果你对技术有追求、希望自己写的代码不仅能用而且有审美价值,那么你肯定会被这本书所吸引的。

(本书有在线视频讲座英文书也全部可以在线阅读)

带着崇敬和赞美,将本书献给活在计算机里的神灵。

“我认为,在计算机科学中保持计算中的趣味性是特别重要的事情。这一学科在起步时饱含着趣味性。当然,那些付钱的客户们市场觉得受了骗。一段时间之后,我们开始严肃地看待他们的抱怨。我们开始感觉到,自己真的像是要负起成功地、无差错地、完美地使用这些机器的责任。我不认为我们可以做到这些。我认为我们的责任是去拓展这一领域,将其发展到新的方向,并在自己的家里保持趣味性。我希望计算机科学的领域绝不要丧失其趣味意识。最重要的是,我希望我们不要变成传道士,不要认为你是兜售圣经的人,世界上这种人已经太多了。你所知道的有关计算的东西,其他人也都能学到。绝不要认为似乎成功计算的钥匙就掌握在你的手里。你所掌握的,也是我认为并希望的,也就是智慧:那种看到这一机器比你第一次站在它面前时能做得更多的能力,这样你才能将它向前推进。”
———— Alan J. Perils (1922 年 4 月 1日 - 1990 年 1 月 7 日)

“本书要讨论的各种问题都牵涉到三类需要关注的对象:人的大脑、计算机程序的集合以及计算机本身。每一个计算机程序都是现实中的或者精神中的某个过程的一个模型,通过人的头脑孵化出来。这些过程出现在人们的经验或者思维之中,数量上数不胜数,详情琐碎繁杂,人和时候人们都只能部分地理解它们。我们很少能通过自己的程序将这种过程模拟到永远令人满意的程度。正因为如此,即使我们写出的程序是一集经过仔细雕琢的离散符号,是交织在一起的一组函数,它们也需要不断地演化;当我们对于模型的认识更深入、更扩大、更广泛时,就需要去修改程序,知道这一模型最终达到了一种亚稳定状态。而在这时,程序中又会出现另一个需要我们去为之奋斗的模型。计算机程序设计领域之令人兴奋的源泉,就在于它所引起连绵不绝的发现,在我们的头脑之中,在由程序表达的计算机制之中,以及在由此所导致的认识爆炸之中。如果说艺术解释了我们的梦想,那么计算机就是以程序的名义执行着它们。

“计算机永远都不够大也不够快。硬件技术的每一次突破都带来了更大规模的程序设计事业,新的组织原理,以及更加丰富的抽象模型。每个读者都应该反复地问自己‘到哪里才是头儿,到哪里才是头儿?’——但是不要问得过于频繁,以免忽略了程序设计的乐趣,使自己陷入一种喜忧参半的呆滞状态中。”

“Lips 有着如此简单的语法和语义,程序的语法分析可以看作一种很简单的工作。这样,语法分析技术对于 Lisp 程序几乎就没有价值,语言处理器的构造对于大型 Lisp 系统的成长和变化不会成为阻碍。最后,正是这种语法和语义的极端简单性,产生出了所有 Lisp 程序员的负担和自由。任何规模的 Lisp 程序,除了那种寥寥几行的程序之外,都饱含着考虑周到的各种功能。发明并调整,调整恰当后再去发明!让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的 Lisp 程序员。

“一台计算机就像是一把小提琴。你可以想象一个新手试了一个音符并丢掉了它。后来他说,听起来真难听。我们已经从大众和我们的大部分计算机科学家那里反复听到这种说法。他们说,计算机程序对个别具体用途而言确实是好东西,但它们太缺乏弹性。一把小提琴或者一台打字机也同样缺乏弹性,那是你学会了如何去使用它们之前。”
—— Marvin Minsky, “为什么说程序设计很容易成为一种媒介,用于表述理解肤浅、草率而就的思想”

“我们所设计的这门计算机科学导引课程反应了两方面的主要考虑。首先,我们希望建立起一种看法:一个计算机语言并不仅仅是让计算机去执行操作的一种方式,更重要的,它是一种表述有关方法学的思想的新颖的形式化媒介。因此,程序必须写得能够供人们阅读,偶尔地去供计算机执行。其次,我们相信,在这一层次的课程里,最基本的材料并不是特定程序设计语言的语法,不是有效计算某种功能的巧妙算法,也不是算法的数学分析或者计算的本质基础,而是一些能够用于控制大型软件系统的智力复杂性的技术。

我们的目标是,使完成了这一科目的学生能对程序设计的风格要素和审美观有一种很好的感觉。他们应该掌握了控制大型系统中的复杂性的主要技术。他们应该能够去读50页长的程序,只要该程序是以一种值得模仿的形式写出来的。他们应该知道在什么时候那些东西不需要去读,哪些东西不需要去理解。他们应该很有把握地去修改一个程序,同时又能保持原来作者的精神和风格。

P.S. “程序必须写得能够供人们阅读,偶尔地去供计算机执行”这句话流传很广,我想大部分人应该都和我一样,认为这句话是在强调代码的可维护性或者干净整洁。但从上下文来看,作者是在强调计算机语言“是一种表述有关方法学的思想的新颖的形式化媒介”,和代码的可维护性什么的没有关系。

[Mac OS X]在终端中打开文件夹窗口

使用 Mac OS X 的时候,因为习惯了在终端中用 VIM 编写代码,所以一般创建文件、编码都是用命令行操作的,但是偶尔还是需要用到 Finder ,比如可能需要查看以下素材图片的大小、想要把HTML文件拖到浏览器中看以下效果。这样的话,如果你的工作目录层次很深的话,就需要点击好多次才可以到达,很不方便。这个时候你可能就会想要下面这个小技巧了:

open .

上面这个命令就是打开当前所在的文件夹,当然你也可以利用 open 命令打开其它的文件夹。

买一赠一:在 Ubuntu 下,使用终端打开GNOME文件夹的命令是:nautilus $PWD

Objective-C Coding Style

一直一来我都没有找到详细明确的Objective-C Coding Style,这让我很苦恼,因为我很关心一些小细节,比如 “{” 的位置,到底应该把 { 和关键字/方法名放在一行:

1
2
3
if(condition){
}else{
}

还是应该把 { 另起一行:

1
2
3
4
5
6
if(condition)
{
}
else
{
}

关于这两种写法,其实争议已久,一般来说都认为把 { 直接放在行尾可以节省屏幕空间,而另起一行写 { 会让代码更易读,因为可以更容易看出 { 和 } 的对应关系。JAVA 和 JavaScript 一般都是采用直接放在行尾的写法,而另外一些语言比如C/C++ 往往会在新的一行写 { 。

那么在 Objective-C 中到底采用哪一种写法呢?官方没有给出明确的编程规范,只有一些命名规范,而官方网站上提供的示例源码也是风格不一,有一些代码甚至夹杂使用了这两种写法。不过根据我的猜测,官方其实鼓励直接把 { 写在行尾,因为在创建项目的时候会根据模板生成一些文件,模板中的代码都是直接把 { 写在行尾的。
查看日志全文 »

[转载]KPI心理学

原文地址:http://jerrylovesrebol.blogspot.com/2010/06/kpi.html(需翻墙)

作者:蔡學鏞

阿里巴巴集团大部分的员工,每季或每半年都要接受一次的KPI考核,看看他绩效如何。关于用KPI来打考核,许多员工其实都有一些负面的看法,而管理层也知道采用KPI有时候会有负面效果,但是没有更好的方法之前,我们还是仰赖KPI。

我已经到阿里巴巴的支付宝上班一年多了,对于KPI,我有四阶段的心理变化,值得描述一下。

刚进公司时,我对KPI的重视程度是70%。大多数的时间,我做的事都是KPI设定的任务,有些事情,虽然不是KPI关注的任务,但只要对公司有利,我依然会去做。这是第一阶段。

后来,我对KPI的重视程度降低到30%。大多数的时间,我做的事都是对公司有益处的事,至于是不是KPI的重点我就比较不在乎了。这是第二阶段。这是对公司最好的阶段。

接著,我发现做正确的事会导致自己的KPI不好,无法升迁,于是我开始变成100% KPI导向。只要不是KPI的内容,我就不愿意做。这是第三阶段。公司把一个员工逼到这个阶段,是很可悲的,对公司也是一个伤害。

第三个阶段不会持续太久,会立刻变成第四个阶段:对KPI重视程度为0%。这表示对于自己在这家公司的前途已经不在乎,准备开始找工作了。我现在正在第四阶段,至于会不会有第五阶段,我就不知道了。
查看日志全文 »

使用 Mac 键盘输入特殊字符

很多时候我们都需要输入特殊字符,例如版权符号:© 。以前碰到这种情况我都是去网站上找一个现有的标记然后复制下来,今天忽然发现其实 Mac 键盘是可以直接输入这些符号的(Win 键盘可能也有办法输入,我没试验过),比如版权符号 © 可以用 Option+G 直接输入,Ω 是 Option+Z …… 从网上找到了几个很好的参考:

1. Macintosh Accent Codes

2. COMPUTER KEYBOARDS - MACINTOSH

3. 100 Mac Keyboard Shortcuts for Creating Symbols

另外 Adobe 网站上还有一个PDF版本的参考文档

要不是无意中看到一本字体设计书中的插图,我可能永远都不会知道原来平常使用最频繁的键盘还藏有这些秘密,世界真奇妙 :)

Face.com 开放 API

Face.com 是一个做人脸识别的网站,虽然人脸识别这个技术只是图像识别里面的一个小分支,但是基于这种技术却可以做出很有创意的功能,比如那个 Auto Smiley

现在 Face.com 开放了一些API,提供了比较丰富的功能,比如判断是否为笑脸、眼睛和鼻子等器官的位置。现在就算你不懂图像处理,也可以利用他们的API来做一些应用了。

相关文档
API Sandbox
示例程序

CSS3 Man

有个家伙用CSS3 + HTML5 + JQuery 写了一个很短的 Spiderman (蜘蛛侠) 的动画,效果还可以:

http://www.optimum7.com/css3-man/animation.html
(需要使用 Safari 或者 Chrome 浏览)

作者还详细讲解了一下制作步骤

如果真的要做动画片的话,还是用 Flash 吧,毕竟生产效率高,不过还是期待 CSS3+HTML5 不断带来惊喜。

Apple VS Adobe

自从Apple禁止使用Adobe Flash 开发的应用程序进入商店之后,Apple 和 Adobe 就全面开战了,搞的我现在的Google Reader 里一时出现了好多争论 Flash 和 HTML5 的优劣的文章。很多经常被 Flash 搞死机的用户说“Flash早该去死了”,很多 Flash 开发者在那里抱怨Apple的专横,甚至号召所有的 Flash 开发人员不要为 Apple 的东西开发应用。

这场战争最后谁是赢家姑且不做论断,但是现在到处出现的那些从技术角度分析的文章实在不值得看。很多人列举了好多Flash 的技术优势来试图说明 HTML5 无法取代 Flash ,恩,或许暂时无法取代,但是如果除了Adobe之外的其它公司都积极推行的话,过几年就说不准了。还有人说大家转战 Android 平台吧,Flash 做的游戏和应用是海量的,早晚 Android 会把 Iphone 打败,但是市场并不只是由应用决定的,还有产品本身,比如我就从来没有发现一块比 iphone/itouch 体验更好的触摸屏。Apple 的东西一般都会很酷,大家都愿意购买,如果市场够大的话,自然会有人为它开发应用。所以那个什么号召不要为Apple开发应用的“开发者同盟”肯定一点用没有,想赚钱的开发者会用自己的代码投票的。而且就算一些独立开发者可以坚决抵制 Apple,但是一些开发者所在的公司如果想去占领 iPhone/iPad 的市场,那么开发者至少在工作时间要放弃Flash——公司是以盈利为目的的组织,技术只是手段。
查看日志全文 »