Javascript Object 杂谈

看到 一个论坛帖子 问到:(类似下面的代码)

var arr = [1, 2, 3];
arr.a = 'a';
arr.b = 'b';

为什么可以这样写?arr 自身到底是什么?

原因其实很简单,因为 js 里一切都是对象,array 也是 object,所以它就能做所有 object 能做的事情,比如,给它加个属性 a

如果 Array 能那么搞,BooleanDate, Function, NumberRegExpString 也可以就不足为奇了。

function toStr(obj) {
  return Object.prototype.toString.call(obj); 
}

function addAttr(arr) {
  for(var i = arr.length-1; i >= 0; i--) {
    arr[i].attr = toStr(arr[i]);
  }
  return arr;
}

function checkAttr(arr) {
  for(var i = 0; i < arr.length; i++) {
    console.log(typeof arr[i], arr[i].attr);
  }
}

var arr = [
    new Boolean(false), 
    new Date(), 
    new Function(), 
    new RegExp('\\w+'), 
    new Number(1.0), 
    new String('str')];
checkAttr(addAttr(arr));

/** output >>
object [object Boolean]
object [object Date]
function [object Function]
object [object RegExp]
object [object Number]
object [object String]
*/

细心的人会发现上面都是使用 new 构造的对象,如果换成是字面方式 (literal) 定义的原生类型 (primitive) 又会是如何呢? 继续阅读“Javascript Object 杂谈”

Font Awesome – Iconic Font for Bootstrap

从 v1.4 开始使用 Bootstrap,从此(内部)项目的 UI 告别了自制样式的时代,风格清新而且使用简便,是目前见过最好使的 CSS 框架。对于哪个妙句 “Build for and by nerds”,我都不知道说什么好了。如果想自定义样式,对于了解 LESS 的是非常容易的,但门槛并不在 LESS 本身,而是在于有些资源在国内是不能访问的。

而 v2.0 之后引入了 由 Glyphicons 提供的 Icons,应用到项目中去,顿时使整个 UI 的感觉上升了一个档次,真是锦上添花的好东西啊。

但是,需求总有惊喜的部分存在。
比如,想在字号较大的 title 位置也应用 icons;
又比如,在一个希望可以起到警惕作用的位置使用 .icon-ban-circle,无论是黑色还是白色(目前只有这两种颜色可供选择)都不能达到这个要求;
幸好是内部系统,不需要兼容什么老的 IE 版本,使用 png 实现的 icons,欸~~

解决方案总是会有的。 继续阅读“Font Awesome – Iconic Font for Bootstrap”

Number 的失真边界

Javascript 中的 Number 是个神奇的类型,它模糊了 整形浮点数 之间的边界,当你拿到一个 Number 的时候,它就只是一个 Number,而且可以很方便地表示非常大的数 Number.MAX_VALUE 或者,或者非常小的数 Number.MIN_VALUE。
实际应用场合里面除了要表示大数和小数,有时还会讲究下精度的。

MDN 的 Number.toPrecision 中有描述 ECMA-262 only requires a precision of up to 21 significant digits. Other implementations may not support precisions higher than required by the standard.”

我们可以知道 JavaScript 的精度在 21 位。究竟是不是代表只要少于 21 位的数都能精确表示呢?简单来个试验就可以知道了。可以猛击这个链接 看看你的浏览器里的 js 到底能有多精确

var arr = [];
for(var i = 0; i< 21; i++) {
  arr.push('9');
  console.log((i+1) + ' : ' + arr.join('') + ' >>' + Number(arr.join('')));
}

我在 Firefox 11 上的结果是到 16 位的时候就已经失真了。

如果是小数的情况:

var arr = ['9.'];
for(var i = 0; i< 21; i++) {
  var str = arr.join('') + '9';
  push((i+1) + ' : ' + str, Number(str));
  arr.push('9');
}

同样地,小数位达到 15 位时出现失真。上面的试验用的是 Number() 进行转换,这与手写同样长度的数字效果是一样的。

幸运的是,这些精度基本够用了。但如果哪位仁兄希望用 JavaScript 来处理一些高精度方面的问题,就必须得注意了,其实 15 位已经是一道坎了。

Inventing on Principle — Always Options in Your Life

超乎想像的 demo,关于创意,关于即时交互——修改的同时看到效果。(很好奇那个是什么编程利器)

看上去都很神奇,但 Bret Victor(苹果的 UI 交互设计师) 主要演讲的并不是谈论具体的技术,而是通过这些 demo 来展示来讨论发明创造中的一些基本的原则。

只要相信,哪些你在乎的,哪些你感觉到不对劲的而你有想法的,哪些你愿意为之而付出的,都是你生命中的可选项。

奇怪的乱码

项目中用到 FreeMarker,在 eclipse 里用 maven 插件 跑 jetty:run,看上去挺美好的。但是一旦修改 FreeMarker 的模版文件(包含中文,UTF-8 编码,无 BOM ),页面一刷新,乱码就出来了。关掉重开可以解决问题。但是总想不明白到底哪里出的问题。

我一开始猜测是 FreeMarker 的读取模版时候的编码问题,经过网上一轮 Google 之后,尝试了各式各样的设置 encoding 方法都不能解决问题。这个问题太困扰了,网上又找不到类似于这种第一轮启动没问题,一修改就出问题的情况,而这个情况在其他人哪里是可以重现的。难道就没有人遇到过?原本只是想简单用用,现在看来得调试进去看看到底出什么问题了。至少需要确认一个问题,究竟是哪个环节出现问题。

又经过一番逐行 debug,得到一个让人惊讶的线索。源代码显示,无论是第几次加载模版,调的都是同一个方法,这部分代码出错的几率不高。而逐行到加载得到模版内容(未经 parse 之前),修改前后加载得到的内容是不一样的,修改后重新加载得到的内容本身就有乱码。

至少,可以还 FreeMarker 一个清白了。凶手又会是谁呢? 继续阅读“奇怪的乱码”

解放 WIN7 的 80 端口

貌似是做了什么更新,或者装了 WebMatrix 之后,就发现个怪事情。Nginx 启动不了,报告端口被占。原来为了省事就改了 81,但想想也不能那么回事啊,80 到底在干嘛呢?

> netstat -ano


80 端口居然被 PID 为 4 的进程所占据,更令人惊讶的是 PID=4 的是 System

Google 了一番,有说 关闭 “World Wide Web Publishing Service” 的,有说是 关闭 IIS 信息服务 的,更有是 修改注册表 的…… 除了注册表实在不想改,其它都试了下,WWW 发布服务根本没找到,IIS 信息服务也没有打开。这时候就蛋疼了。

往往疼能激发潜能。在将所有服务按状态排序之后,逐一检查所有已启动项。迅速得到一个可疑项:“Web 部署代理服务”。

设置手动启动并禁用之。

再检查 80 端口,成功解放。

真搞不明白,为啥微软要搞那么多名目来侵占跟 System 毫不相干的 80 端口呢?

明知是错的,你还会延续下去吗?

同事跟我说,在某个类里面,有个 populate 方法可能有 bug。我随机打开那个类文件,查找一个叫 populate 的方法,那个具体步骤是这样(不具体的话看不出来到底会浪费多少时间),IDE 里用 pop 开头来过滤方法列表,但很遗憾,没看到叫 populate 的方法,却有以 populate 为前缀的几个方法。于是向同事确认,他也没看就说,就叫 populate。我还是相信他的,于是猜想可能是代码没更新,接着做更新,还是没有,可能不在 trunk 上而在分支里,几番周转无果,回到最初的类文件,绝望之中,竟然在方法列表里发现了一个叫 pupulate 的方法。

一股冏上心头泪千行的感觉。作为一个相对底层的类,使用率还不低的情况下,居然有个方法名字错了整整一年甚至更长。

同样是错误,那个 github 史上评论最多的一次 commit(原地址已经 404,可以看其它人的文字记录 或者 google “github giant bug”来重温)。那个要命的空格,让我笑到肚子疼。

rm -rf /usr /lib/nvidia-current/xorg/xorg

好歹人家也可怜地表示 sorry 了。

是不是一个错误只要不影响软件的正常使用,就无须为一些错误感到内疚,甚至会继续延续下去?

在日常开发当中,错误被忽略被延续的情况时有发生。程序员的基本技能技能 ctrl+c, ctrl+v ( or ⌘C, ⌘V ) 以及 IDE 的自动补全就是延续错误的帮凶(当然 IDE 是无罪的,如果没有第一次错误,IDE 是不会乱搞恶作剧的)。延续错误似乎是零成本的,但是修正却是有成本的,会带来不稳定的感觉。 继续阅读“明知是错的,你还会延续下去吗?”

TimeMachineEditor

Time Machine 是个好东西,使用上也极其便利,基本上只有一个配置选择,ON / OFF。一旦选择 ON 并连接好外接设备之后,后面的事情就不用操心了。

为什么 Time Machine 没有地方让我们自己去设定备份周期呢?也许设计本意是好的,只要备份设备有空间,免得太费神。只是,喜欢折腾的人就喜欢折腾。一番 google 之下,找到了这个 TimeMachineEditor

TimeMachineEditor 使用起来特简单,可以选择定期Interval)的方式,可以设定每隔 N 个小时备份一次;也可以选择日程定期Calendar Interval)的方式,比如每天的什么时候,每周星期几,每个月几号。但是只是这样设定是还不够的,必须先关闭了 Time Machine 的自动备份,并且开启它自己的开关,才会生效。

这里我觉得这个软件的 UI 设定是有点问题的。左下角的开关,和右下角的 Apply 按钮两个都存在的会让我感觉混乱,必须看一下 FAQ 才搞清楚到底是怎么一回事。而且,如果它可以在我们选择了启用的时候自动关闭 Time Machine 那就更好了。像它这样简单的功能的软件,在打开软件的时候有个提示就可以让用户更加清楚怎么操作了。而且只需要三个按钮就够了,开启ON),应用设置Apply)和 关闭OFF)。一开始只有开启按钮,开启了之后,变成两个按钮,应用和关闭。这样操作起来更加自然。

TimeMachineEditor 的功能还是不错的,还是免费的哦。

更换了 syntax highlight 插件

其实是个遗留问题。之前是用 Google Syntax Highlighter for WordPress,用起来也还不错,只是有些时候贴写 bash 代码,或者终端里的回显信息时候,真不知道该使用那种语言来显示高亮好。

直到最近开始写有关 Lisp 的 状况系统 与 异常处理 时,发觉情况有点糟糕啊,高亮结果都乱套了。然后跑到它的项目主页去找解决办法,看看有没有别人已经做好的扩展,或者看看怎么自己去扩展一下。结果是比较让人失望的,连怎么扩展的说明没有,也不寄望能找到现成的了。

但似乎又不能怪它,人家已经在主页上写了“This page is OLD, Head over to http://alexgorbatchev.com/wiki/”。那似乎是个更好的解决方案。然后又 google 到了 WP SyntaxHightlighter (在 wordpress 插件库里有一大堆名字很类似的插件,需要点眼力,或者精准查找)。这个插件所使用的正是它。这个插件支持多种配色方案,更吸引我的是下面有列出已经有人做了 Clojure 的扩展(Clojure 是 JVM 上的 Lisp)。

换插件是很容易的,admin 里点几下就搞定了。问题剩余两个:

  1. Clojure 扩展不是原生支持的,需要自行添加到插件中去
  2. 原有 post 里面的 <pre> 标签都需要做些修改,由 class=”lang” 改为 class=”brush: lang”

PHP 我不是很熟,不过靠猜,找到了一个文件(wp-syntaxhighlighter.php)里面有类似支持语言的数组,照例子改了下上传。一开始还不行,后来搞清楚了,它会保存选项到数据库里面,reset 一下就好了。

第二个问题没想到什么批量的办法,花了些时间,顺便把以前写的 post 都重温了下,虽然看得人不多,评论也不多,但是这些都是很好的见证。想起曾经有个时刻,大家都会开个 blog,还很认真的写过一阵,还都写得不错,有观点,有感情。相比之下,我在语文表达障碍阴影底下,只会写些技术文章来凑个热闹。

而随着热潮的退却,大家好像被 reset 了一样,也没有人写个告别博客什么的,只是不再写了。过程是缓慢的,没有人会感到不舒服,不会像断奶,学行走,上学,毕业那样会有许许多多的思想冲突发生。它连个状态切换都不是,只是一种变化跟随。大概无须要为这种事情赋予个什么意义,有人会选择做,有人会选择不做,但如果选择了做,请尽情享受那个过程。

我也作出了选择,我会继续追随梦想,分享美好的瞬间,分享独立的思考,这里是我的梦想飞行器。