您现在的位置:主页 > 香港四海图库总站 >

最准买马网站

文章来源:本站原创 发布时间:2019-06-05 点击数:
c?JavaScript 的死与生_知识库_博客园
很好的一篇文章:JavaScript is Dead. Long Live JavaScript!,下面是概要翻译与我的阅读笔记。  JavaScript 的成功得益于在正确的时间出现在正确的地点。JavaScript 的兴起与浏览器的支持息息相关。你瞧,VBScript 就没这么好运气。  JavaScript 很流行,但它有先天缺陷。Brendan Eich 起初只花了 10 天时间就把 JavaScript 设计出来了,作为 JavaScript 之父,BE 如是说:与其说我爱 JavaScript,不如说我恨它。它是 C 语言和 Self 语言一夜情的产物。十八世纪英国文学家约翰逊博士说得好:“它的优秀之处并非原创,它的原创之处并不优秀。”  (摘选自阮一峰的翻译:JavaScript 产生记)  JavaScript 的不足,最明显之处是语法。  糟糕冗长的语法  可选参数和默认值function(a, b, option) { option = option || {}; // ...}  上面的代码中,option 是可选参数,当没有传递时,默认值是 {}. 然而,传递的 option 值有可能是假值(false 值)。严格来写,得如下判断:function(a, b, option) { option = arguments.length > 2 ? option : {}; // ...}  注意:option = typeof option !== 'undefined' ? option : {} 也有可能是错误的,因为传递过来的可能就是 undefined.  当不需要 b 参数,删除后,基于 arguments.length 的判定很容易导致忘记修改而出错:function(a, option) { option = arguments.length > 2 ? option : {}; // ...}  如果能增加以下语法该多好呀:function(a, b, option = {}) // ...  Let  闭包很强大,也很恼火:for (var i=0, ilen=elements.length; i<ilen; i++) { var element = elements[i]; LIB_addEventListener(element, 'click', function(event) alert('I was originally number ' + i););}  上面的代码经常在面试题中出现,解决办法是再包裹一层:for (var i=0, ilen=elements.length; i<ilen; i++) { var element = elements[i]; (function(num) { LIB_addEventListener(element, 'click', function(event) alert('I was originally number ' + num);); }(i));}如果直接支持 let 语法该多好呀:function attachListener(element, num) { LIB_addEventListener(element, 'click', function(event) alert('I was originally number ' + num););}for (var i=0, ilen=elements.length; i<ilen; i++) attachListener(elements[i], i);  模块  模块模式是一种无奈的选择:var event = (function() { // private variables var listeners = []; function addEventListener(f) listeners.push(f); function clearEventListeners() listeners = []; // ... // export the module's API return addEventListener: addEventListener, clearEventListeners: clearEventListeners // ...;}());如果原生支持该多好呀:module event { // private variables var listeners = []; export function addEventListener(f) listeners.push(f); export function clearEventListeners() listeners = []; // ...}(function() import event; // ...());继承  JavaScript 要通过原型链来实现继承:function Employee(first, last, position) // call the superclass constructor Person.call(this, first, last); this.position = position;;// inherit from PersonEmployee.prototype = Object.create(Person.prototype);Employee.prototype.constructor = Employee;// define an overridding toString() methodEmployee.prototype.toString = function() // call superclass's overridden toString() method return Person.prototype.toString.call(this) + ' is a ' + this.position;;如果能写成下面这样该多好呀:class Employee extends Person { constructor(first, last, position) super(first, last); public position = position; update(camera) return super.update() + ' is a ' + position;}感悟  ECMAScript 委员会已意识到 JavaScript 在语法层面上的不足。在 Harmony 规范中,以上所有语法均已提案。  我们什么时候才能使用以上语法呢?  只要有宏(Macro)  Lisp 语言的宏特性非常强大。通过宏,你可以根据自己的喜好定义想要的语法格式。宏特性使得 Lisp 成为一门“可编程的编程语言(the programmable programming language)”.  JavaScript 没有宏。给类 C 语言添加宏特性,目前依旧是个研究课题,很有难度。  只要有宏,我们就可以自定义语法。但 JavaScript 的宏特性遥遥无期,还是找找其他路子吧。  Harmony  Harmony 规范里的语法扩展,可能是我们所有人的梦。Harmony 有可能成为 ECMAScript 6 规范。在这之前,我们需要等待,耐心等待。  截止 2011 年 5 月,w3school 显示 IE6 的市场份额还有 2.4%. Net Market Share 显示 IE6 占有 10.36% 市场份额。还有 IE7 的市场份额也不少。这些老旧浏览器短期内不会退隐市场,对于商业公司来说,比如 Amazon,不可能舍弃这批用户。糟糕的现状。(中国大陆更惨,IE6/7 还占有 40% 多市场份额)  我们不能寄期望于“IE 该死”这类呼吁来让用户升级。听到过一种说法:IE 用户仅会在更换电脑硬件时,才升级浏览器。悲催的是,对于普通用户来说,收收 email, 上上 Facebook, Twitter, 现有的硬件已足够。没有理由让他们去花一笔钱。  Goggle Apps 最近宣布,从 2011 年 8 月开始,将停止支持 IE7.   通过各种保守估量,Amazon 的网站开发者,用上 Harmony 语法扩展,要一直等到 2023 年!  风华正茂的你,愿意等待 10 多年后,再用上这些好用的语法吗?  JavaScript 已死  死因:分号癌。(semicolon cancer. 作者的调侃,意指语法导致 JavaScript 死去)  通过上面的分析可以看出,宏特性实现太难,Harmony 规范的实现则遥遥无期。大量程序员开始书写 JavaScript, 其中有很多人已经厌倦或开始厌倦 JavaScript 冗长糟糕的语法。我们需要新的语法,我们不想等待!JavaScript,作为源码编写语言,已经死了!  JavaScript 先生,你曾有过辉煌的统治。我们与你,有过甜蜜的回忆,一起产出过很多有趣的应用。祝福逝者安息。  JavaScript 长存  程序员喜欢掌控自己的命运。作为源码编写语言,JavaScript 已死。我们可以选择或创造另一种更好的源码语言,将其编译成 ECMAScript 3 的语法格式。  JavaScript 的新生,是作为编译目标(compilation target)。  编译成 JavaScript 的语言  能编译成 JavaScript 的语言有很多。我在 1997 年时,收集过一份列表。包括:JavaScript 扩展语言:已死的 ECMAScript 4, Narrative Script, Objective-J.已存在的语言:Scheme, Common Lisp, Smalltalk, Ruby, Python, Java, C#, Haskell 等。还有一些崭新的语言:HaXe, Milescript, Links, Flapjax, 专门为 web 编程而设计。  在这些编译器项目中,Goggle 的 GWT Java-to-JavaScript 编译器有可能是最成功的一个。 然而悲剧的是,现实项目中,很少看到 GWT 的身影。原因如下:  1. 维护成本很高。编译器可能有 bug. 假设你在一个大型项目中,发现了编译器的一个 bug, 作为保护者,除了维护源码,你还得维护编译器。天哪,你有这个本事吗?你有这个本事,CEO 也不情愿花这个钱呀。  2. 调试麻烦。Firebug 报了一个错,报的是编译后的行号。老板站在你背后:赶快啦,小伙子!可是这该死的编译后代码,究竟对应哪一行源码呀?  3. 招聘不到人。假设你使用 Objective-J 开发一个项目,但人手不够。赶忙招人,HR 说 1000 个人里面,只有 100 个听说过 Objective-J, 另外 900 个只听说过 JavaScript. 结局是你每找一个新人,都得先培训一把,真是糟糕透顶。  虽然编译器有以上各种不是,但各种编译器仍旧如雨后春笋大量涌现。毫无疑问,编写 JavaScript 编译器非常酷。给我酬劳,我也想写一个。  在上面的编译器列表中,有一个非常有名的引起过很大轰动的:CoffeeScript. 我们来谈谈它。  CoffeeScript  为什么 CoffeeScript 如此火爆?我到现在为止也没想明白。是因为给空白赋予了意义,还是带箭头的函数语法?每念及此,我的胃就忍不住波涛汹涌。CoffeeScript 有很多新特性:default parameter values, rest parameters, spread,一肖中特马, destructuring,fixing the whole implied global mess… CoffeeScript 很多特性是 Harmony 规范的一部分,有可能在未来浏览器中直接支持。CoffeeScript 能让人立刻满足。@pyronicide 在 Twitter 上说:#coffeescript 支持函数默认参数值,这太令人兴奋了。  在 TXJS 2011 大会上,Douglas Crockford 也表示:CoffeeScript 无疑是个好东东。  CoffeeScript: Accelerated JavaScript Development 一书的作者说:@trevorburnham[...] CoffeeScript 不是将 JS 变成 Ruby 或 Python, 而是通过一套语法,来更好地发挥 JavaScript 内在的优秀。  Douglas Crockford 认为 JavaScript 有好的方面,并开发了 JSLint 工具来保证开发者远离 JavaScript 中的糟粕。JSLint 答应的语法子集值得拥有自己的名字,我们不妨称之为 GoodScript.  ECMAScript 5 则引入了 "use strict" 指令来限制 with 等语法的使用。  CoffeeScript, GoodScript, ECMAScript 5 的目标是一致的:远离糟粕,同时提供有用的、安全的语言特性给你。  GoodScript 没有提供新特性,ECMAScript 5 的严格模式,大部分浏览器还不支持。然而,我们不想等待。  剩下的挑选是 CoffeeScript. 好处:特别适合 web 开发。这可能是其他 JavaScript 编译器没做或做得不好的地方。CoffeeScript 对 JavaScript 的封装适度。这样能使得编译后的代码比较容易阅读,调试也就不那么困难了。  CoffeeScript 看起来就像是书写 JavaScript 代码的一套宏。  CoffeeScript 的编译器提供客户端版本。这样,使用者可以自由选择,开发者也可以快速开发新功能,而不受标准的局限。由社区的愿景和需求推动 CoffeeScript 的发展,这很不错。  发明自己的语言  你可以去做,这会是一个很好的练习。作为 JavaScript 编译器的开发者,将拥有无上荣耀。  发明自己的语言,危险之处在于:你认为最终你将比 JavaScript 做得更好。语言设计很难,我敢打赌你的语言很难扩大市场份额。CoffeeScript 尚未进入青春期,就已经有埋怨的声音了。  你可能会为自己的编译器能编译出简单、可读的代码而骄傲。可是,一碰到特别情况,你就会郁闷得想撞墙。  你的语言里将会出现惯用法。接着,你立刻会发现有人会破坏这些惯用法(除非你的语言刚好支持宏)。  风凉话就不多说了。立刻去开发自己的语言吧,你会成为一个很好的程序员。  作为编译目标语言,JavaScript 缺少什么?  作为编译目标语言,JavaScript 重获新生。在 JSConf.US talk 中,Brendan Eich 表示:Harmony 规范的目的是让 JavaScript 成为更好的编译目标。  编译后的 JavaScript 有可能比手写的 JavaScript 运行效率更低,这就和编译后的 C 有可能比手写的汇编语言效率更低一样。幸运的是,JavaScript 的瓶颈主要在 DOM 操作上,语言本身的效率损耗相对可以接受。虽然话是这么说,但一些高效的源码语言编译后,由于 JavaScript 本身的问题,可能极其低效,以致于无法在真实环境中使用。Harmony 规范中已经有部分特性能保证避免这类问题。  合理的尾部调用function isEven(number) { if (number === 0) return true; else return isOdd(number - 1);}function isOdd(number) { if (number === 0) return false; else return isEven(number - 1);}isEven(100000); // InternalError: too much recursion上面的代码,在目前的浏览器中运行,会堆栈溢出。  可以通过蹦床(trampolines) 技巧来优化:function bounce(ret) { while (typeof ret === 'function') ret = ret(); return ret;}function isEven(number) { if (number === 0) return true; else { return function() return isOdd(number - 1);; }}function isOdd(number) { if (number === 0) return false; else { return function() return isEven(number - 1);; }}bounce(function() return isEven(100000);); // true通过 bounce 方式,在运行 isOdd(99999) 时,isEven(100000) 已经完成并从堆栈中退出了,因此不会造成溢出。  幸运地是,ECMAScript Harmony 已经考虑到了这一点,会自动进行优化。这对程序开发者和编译器开发者都是有益的。  Lambdas  lambda 并不奇妙。简言之,lambda 就是可调用的东西,比如 function, 但需要遵守 TCP(Tennent 一致性原则,Tennent’s Correspondence Principle)。TCP 要求:用一个紧邻的 lambda 对表达式或代码块进行封装,不会改变被封装的代码的含义。  很显然,JavaScript 的 function 不是 lambda:function one() return 1;one(); // 1封装后,返回值发生了变化:function one() { (function() return 1;());}对于接受两个参数并将其求和的代码块,lambda 语法提议写成:a, b  对于上面的例子,采用 lambda 封装将保证返回值和封装前一样:function one() { (return 1;());}one(); // 1lambda 块的稻草人提案目前还没有提升到 Harmony 规范中,让我们一起努力吧。  浏览器缺少什么?  JavaScript 的兴衰存亡离不开浏览器。JavaScript 的新生,也需要浏览器的靠谱支持。  Mozilla 发起了一个 SourceMap 项目,这可以使得在调试编译后的代码时,能映射回源码的对应代码行。这太 cool 了,能极大的减少调试成本。  听说 Webkit 的小伙子们也在干同样的事情,惋惜我找不到任何证据了-.-  通晓数种语言  JavaScript 在浏览器上的垄断,意味着前端程序员都会同一门语言。然而,编译器的差异性,会使得 CoffeeScript 程序员,很难立刻看懂基于 Traceur 的 JavaScript 代码。  这种分歧不可避免。比如有 C,马报开奖结果, 同时有 C++ 和 Objective-C 等各种语言。Java 也一样,基于 JVM 还可以选择 Clojure 或 JRuby. 微软意识到这一点,开发了 CLR. C#, Basic, IronPython 等都可以运行在 CLR 上。  前端中的沟通障碍并非新鲜事物。一个 Dojo 程序员,难以立刻明白基于 jQuery 或 YUI 的代码。  拥有多种源码书写语言会增加社区的沟通障碍。程序员仍需要了解 JavaScript. 至少一段时间内程序员还需要懂得 JavaScript. 但在短短几年后,他们可能会更了解其他源码语言。  总结  能有机会目睹 JavaScript 的新生,是件很棒的事情。在 JavaScript 编译的竞争中,很难说谁会最终赢得市场份额,但毫无疑问,这肯定会很有趣。如今,CoffeeScript 蓄势待发,但我相信许多其他成功的源码语言将接踵而至。  你的想法呢?