Javascript命名禁区

04月 1st, 2011

大家都知道的,当我们使用Javascript保留字作为标识符时,会引起程序报错。
大家不一定知道的,当我们使用top, fullScreen, screen等作为标识符时,也会引起程序报错或者执行异常。

报错还好,怕的就是没有报错,而当项目上线后,在某些特定环境下,它才执行异常,这时候来查错才真的要人老命。所以,我们不能留下任何黑洞,我们必须清楚,浏览器端的Javascript到底有哪些命名禁区。

我自己的亲身经验:
1、input元素上扩展start方法。
在做一个动画框架时,为了方便链式调用,我给元素扩展了一个start的方法,并且测试通过,以为万无一失,这个方法名没被占用,直到碰到这样一段代码:

  1. var btn = lib.getElem('input'); // 获取到一个input元素
  2. btn = lib.extend(btn); //  扩展方法
  3. btn.start();

在IE下报错了,原因是:
input元素已经有了start这样一个属性( input.start 设置或获取视频剪辑文件应该开始播放的时间。 )
2、定义一个fullScreen的全局变量。

  1. var fullScreen = function(){
  2. ....//突出显示页面中某一块内容
  3. }
  4. alert(fullScreen); // ff中为false

两次的教训,我觉得有必要整理一份Javascript命名禁区表了,不可能完全记住,但至少有一个大体印象。

一、标识符允许的字符集。
在ECMAScript V3中,标识符除首字母外,允许使用除 (./=?:&#\{}()<>[]|~!’”\*^) 等特殊字符外所有的unicode字符集。

二、变量名、函数名、循环标记命名禁区。
1、保留字
break delete function return typeof case do if switch var catch else in this void continue false instanceof throw while debugger finally new true with default for null try
2、未来保留字
abstract double goto native static boolean enum implements package super byte export import private synchronized char extends int protected throws class final interface public transient const float long short volatile
3、扩展列表
as is namespace use arguments encodeURI Infinity Object String Array Error isFinite parseFloat SyntaxError Boolean escape isNaN parseInt TypeError Date eval Math RangeError undefined decodeURI EvalError NaN ReferenceError unescape decodeURIComponent Function Number RegExp URIError

4、IE全局变量
status onresize onmessage parent onhashchange defaultStatus name history maxConnectionsPerServer opener location screenLeft document onbeforeprint screenTop clientInformation onerror onfocus event onload onblur window closed screen onscroll length frameElement self onunload onafterprint navigator frames sessionStorage top clipboardData external onhelp offscreenBuffering localStorage onbeforeunload
5、FF全局变量
getInterface addEventListener loadFirebugConsole console window cehomepage document netscape XPCSafeJSObjectWrapper XPCNativeWrapper Components sessionStorage globalStorage getComputedStyle dispatchEvent removeEventListener name parent top dump getSelection scrollByLines scrollbars scrollX scrollY scrollTo scrollBy scrollByPages sizeToContent setTimeout setInterval clearTimeout clearInterval setResizable captureEvents releaseEvents routeEvent enableExternalCapture disableExternalCapture open openDialog frames applicationCache self navigator screen history content menubar toolbar locationbar personalbar statusbar directories closed crypto pkcs11 controllers opener status defaultStatus location innerWidth innerHeight outerWidth outerHeight screenX screenY mozInnerScreenX mozInnerScreenY pageXOffset pageYOffset scrollMaxX scrollMaxY length fullScreen alert confirm prompt focus blur back forward home stop print moveTo moveBy resizeTo resizeBy scroll close updateCommands find atob btoa frameElement showModalDialog postMessage localStorage
这是最容易被忽视的部分,有的变量允许你重新设置,但最好不要随意去占用它,除非你非常清楚你在干什么,及可能造成的后果

三、属性方法命名禁区。
1、保留字
break delete function return typeof case do if switch var catch else in this void continue false instanceof throw while debugger finally new true with default for null try
2、未来保留字
super export import extends const class

* 这里主要针对字面量对象{},eg:

  1. var testObj = {class: 3}; //ie将报错
  2. var testObj = {}; testObj['class'] = 3 //则不会

阅读全文 »

找出字符串中出现最多的字符,出现了多少次?

12月 16th, 2010

经典的时候看到的,据说是百度的前端面试题。尝试了几种不同的方法,并进行了性能测评,与大家分享。

一、最精典的方法。
思路:遍历字符串,逐个取出字符,用replace将目标字符替换为空,用原字符串长度减去新字符串长度,获取目标字符出现次数,最终取出出现频繁最高的字符。

提示:你可以先修改部分代码再运行。

这是最常用、最传统的办法。
走套路可不带劲,开始探索新的方法,于是有了下面的改进版 -

二、最取巧的办法。
思路:
1、先将字符串转换成JSON数据。eg.‘波rr波’ -> {’波’: 2, ‘r’: 2} 。
2、再以JSON数据的值为索引转换成数组。eg.{’波’: 2, ‘r’: 2} ->[2]:’波’,'r’。
3、这样数组的最后一项即出现最多的字符。

提示:你可以先修改部分代码再运行。

探索是无止境的,方法二确实以精简的代码完成了同样的功能,但是这种取巧的方式,代码的可读性似乎不是太好。有没有第三种方式,两者兼顾呢,继续改进 -

三、最精简的办法。
思路:充分利用数组的sort方法根据出现频繁排序,首先将重复的字符全部放在一起并分别用正则匹配为数组,再根据数组长度排序。
PS:这里重在重新排列数据,最终取值不全(多个字符并列最多时只能取一个)。

提示:你可以先修改部分代码再运行。

从近20行代码压缩到3行代码,代码得到了进一部精简,并且保持了清晰的逻辑,大功告成!

真的大功造成了吗?
当然不是,相信不少童鞋已经注意到了,上面优化的过程中,性能问题我只字未提,而这恰恰又是优化的主旋律。
好了,我们开始性能测试 -

Update2010-12-16:
此前由于测试数据采样不够,只测试了一组大量重复字符的数据,导致测试结果有失公正。
感觉hutia提醒,重新采样测试。

性能测试:
将测试数据放大,比较查找时间。

提示:你可以先修改部分代码再运行。

测试结果:(运行上面的代码查看详情)

  大量重复字符的数据 没有重复字符的数据 模拟真实环境数据
方法一 IE6:15ms FF3.6:4ms IE6:1600ms FF3.6:4300ms IE6:187ms FF3.6:248ms
方法二 IE6:47ms FF3.6:9ms IE6:125ms FF3.6:25ms IE6:63ms FF3.6:13ms
方法三 IE6:78ms FF3.6:15ms IE6:1500ms FF3.6:14ms IE6:219ms FF3.6:10ms

测试结论:
当重复字符较多时 - 各浏览器均“方法一”速度最快;
当重复字符较少时 - IE6下“方法二”速度最快,FF3.6下“方法三”速度最快。
从适用性和性能角度纵使考虑,最终推荐 方法二

原因分析:
当目标字符串重复字符较多时 -
方法一性能损耗主要在replace方法,但由于循环次数大大减少,从而取胜;
重复字符较少时 -
方法二虽然进行了两次循环,但每次循环计算量较少,从而取胜;
方法三在FF3.6中小胜,虽然进行了两次循环,两次数组转换,但由于调用内置的sort方法,从而取胜。

总结:
整篇文章虽然以精简为主线,其实我之前对性能就有所预料,本想借此唤起大家对性能的重视,不要为了精简而精简,小心当我们欢呼雀跃时,潜在的风险正在徐徐袭来。
但整个过程出现了一段插曲,给了我一记警钟,在将文章发表到经典论坛后,hutia对我的测试结果表示了异议,于是重新测试,发现由于我原来数据取样不够,而导致测试结果有所偏颇。
幸亏有一这么一段插曲,才让我更意识到,测试环节照样需要谨慎,感谢hutia。
真的只有在交流中才会发现自己的不足,以后也会经常把自己的东西晒出来,给大家评论,指点。

你有更优的解决办法吗?你对测试结果表示怀疑吗?欢迎大家拍砖。
你有什么疑点吗?你曾碰到过类似的场景吗?欢迎大家跟帖一起交流。

告别乱码 - 网站编码问题汇总

10月 19th, 2010

相信各位同行或多或少都会碰到过乱码的问题。
从来没有?相信我,只是时候未到,在这行混,迟早会碰到的。
当然,如果你对各类编码非常了解,对浏览器脾气摸得很清楚了,你可以避开或者快速解决此类问题。
希望这篇文章对你有所帮助。

一、为什么会出现乱码?
  在计算机中,我们储存的信息都是用二进制码表示的。我们文字和符号用的二进制代码的互相转换,就是编码,转换需要一种规则,就是字符集(charset),我们常用的字符集例如:ascii,gb2312,unicode。
不同的字符集所存储的内容不同, 比如“太平洋”三个字采用gb2312对应的值为4411 3829 4983,utf-8对应为E5 A4 AA E5 B9 B3 E6 B4 8B,这样,当一个gb2312的文件嵌入一个utf-8的文件的时候,问题就来了。

二、ANSI, Unicode, UTF-8, Encode, Charset, HTML实体… 我快疯了
疯完了没,没昏就行了,别着急,听我一一道来。其实这只是同一样东西在不同场合的应用。
A. ANSI, Unicode, UTF-8
这几个归为一类,它们是文件编码。
ANSI指当地编码,比如在大陆它指GB2312,在台湾它指GBK(Win中记事本保存文件的时候的默认选项就是它)。
Unicode是一个通用字符集,它是一个编码标准,这个和GB2312是对应的,但因为字符集过大,Unicode有它的特殊性,在不同应用场合,有不同的具体实现手法,比如应用于互联网传输,采用的存储与传送格式是UTF-8,Windows应用UTF-16,Linux 应用UTF-32。
B. Charset
HTML中的Charset,CSS中的@charset,XML中的encoding等,这几个归为一类。
它们是告诉浏览器如何解码。比如psd后缀是告诉系统这是Photoshop源文件,同样charset设为gb2312是告诉浏览器这是一个简体中文的网页。

C. Encode
Encode和encodeURI,encodeURIComponent归为一类。
这在下一节中进行比较详细的介绍。当浏览器提交数据给服务器时,特殊字符中文一般浏览器会自动编码,但存在部分保留字符,比如”# /”等,这时候需要encode等进行转换。
D. HTML实体
当网页中需要插入某些特殊字符时,需要用到HTML实体,比如插入<,可以使用&lt;或者实体编码&#60;。
阅读全文 »

初探浏览器内核

10月 19th, 2010

一、还原页面渲染流程。
  你应该了解真相,真相会让你自由。 -《圣经》

  不知道大家是否玩桌球,常玩桌球的童鞋肯定知道,打好桌球,母球的控制最重要,当然要控制好它,这需要日积月累的练习,但是,如果你深入地分析过,你击球的位置和角度,对母球旋转,碰撞后路线变化的影响,了解了整个物理过程后,这将会让你事半功倍。

  废了这么多话,其实还只说了文章第一句,你应该了解真相(轻点砸,嘿嘿)。每天与浏览器打交道的我们,如果对浏览器内核的实现了如指掌,那无疑,你将可以做出最优秀的页面。有童鞋可能要喷我了,能达到这水平我直接去开发浏览器了。是的,我们不可能了解到它的每一个细节,但是我们可 以大体地了解它,把握她的性情,摸清他的脾气。

  目前,除了市场占有率最高性能最糟糕的Trident(IE内核),性能最棒市场占有最低(相对)的 Webkit(Chrome&Safari),常见的还有Gecko(FireFox)、Presto(Opera)。我们没这么多时间和精力, 也没必要逐个了解,因为它们干的都是同一件事,实现的手法大体一致。

阅读全文 »

奇技淫巧之图片切割

10月 10th, 2009

DEMO1(随机出现): http://cnwander.com/demo/puzzle_effect/
机器配置好的可以将图片切得更细一点 (变量xNum,yNum)
DEMO1(规则运动): http://cnwander.com/demo/puzzle_effect/index2.html
测试:IE6、IE7、FF3.014

突发奇想的效果,主要突出构思,效果还比较粗糙,好好创意一下,应该可以引申出一些比较有新意的图片切换效果。
没什么特别的东西,思路自己看DEMO吧。

如蒙转载,请注明出处 cnwander.com

仿土豆豆单Photo Slideshow

10月 7th, 2009

DEMO: http://cnwander.com/demo/slideshow/
photo slide show
测试:IE7、FF3.014
阅读全文 »

[JS小游戏]2D桌球

09月 30th, 2009

DEMO: http://cnwander.com/demo/billiards/
js小游戏2d桌球
贴出一些关键代码稍作解释,有兴趣的同学看看。
阅读全文 »

[JS小游戏]贪吃蛇+详细注释

09月 20th, 2009

DEMO: http://www.cnwander.com/demo/snake/
老实说,游戏并不是Javascript的强项,特别是这种画面刷新频率比较高的游戏,还是用AS来得流畅,至少目前来说是这样的。所以我也并没打算在这块进行太深入的研究,写游戏完全是觉得好玩,可以维持对Javascript的学习兴趣。对新手来说,看小游戏代码也是最能激发兴趣的,所以我进行了比较详细的注释,希望对大家有所帮助。
源代码:
阅读全文 »