0

0

JavaScript的死与生

高洛峰

高洛峰

发布时间:2016-11-25 11:32:25

|

1206人浏览过

|

来源于php中文网

原创

javascript的成功得益于在正确的时间出现在正确的地点。javascript的兴起与浏览器的支持息息相关。你瞧,vbscript就没这么好运气。

JavaScript很流行,但它有先天缺陷。Brendan Eich当初只花了10天时间就把JavaScript设计出来了,作为JavaScript之父Brendan Eich如是说:

与其说我爱JavaScript,不如说我恨它。它是C语言和Self语言一夜情的产物。十八世纪英国文学家约翰逊博士说得好:“它的优秀之处并非原创,它的原创之处并不优秀。” 
JavaScript的不足,最明显之处是语法。

糟糕冗长的语法 可选参数和默认值

function(a, b, option) {  
  optionoption = option || {};  
  // ...  

上面的代码中,option是可选参数,当没有传递时,默认值是{}.然而,传递的option值有可能是假值(falsy值)。严格来写,得如下判断:

立即学习Java免费学习笔记(深入)”;

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  var element = elements[i];  
  LIB_addEventListener(element, click, function(event) {  
    alert(I was originally number + i);  
  });  

上面的代码经常在面试题中出现,解决办法是再包裹一层:

for (var i=0, ilen=elements.length; i  var element = elements[i];
  (function(num) {
    LIB_addEventListener(element, click, function(event) {
      alert(I was originally number + num);
    });
  }(i));
}
如果直接支持let语法该多好呀:

for (var i=0, ilen=elements.length; i  var element = elements[i];
  let (num = i) {
    LIB_addEventListener(element, function(event) {
      alert(I was originally number + num);
    });
  };
}
模块
模块模式是一种无奈的选择:

如果原生支持该多好呀:

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 Person  
Employee.prototype = Object.create(Person.prototype);  
EmployeeEmployee.prototype.constructor = Employee;  
 
// define an overridding toString() method  
Employee.prototype.toString = function() {  
  // call superclasss 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 positionposition = 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 能让人立刻满足。

爱派AiPy
爱派AiPy

融合LLM与Python生态的开源AI智能体

下载

@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) {  
      retret = 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;  
  }());  
}  
 
one(); // undefined 
对于接受两个参数并将其求和的代码块,lambda 语法提议写成:{|a, b| a + b}

对于上面的例子,采用 lambda 封装将保证返回值和封装前一样:

function one() {  
  ({||  
      return 1;  
  }());  
}  
 
one(); // 1 
lambda 块的稻草人提案目前还没有提升到 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蓄势待发,但我相信许多其他成功的源码语言将接踵而至。

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
全国统一发票查询平台入口合集
全国统一发票查询平台入口合集

本专题整合了全国统一发票查询入口地址合集,阅读专题下面的文章了解更多详细入口。

19

2026.02.03

短剧入口地址汇总
短剧入口地址汇总

本专题整合了短剧app推荐平台,阅读专题下面的文章了解更多详细入口。

27

2026.02.03

植物大战僵尸版本入口地址汇总
植物大战僵尸版本入口地址汇总

本专题整合了植物大战僵尸版本入口地址汇总,前往文章中寻找想要的答案。

15

2026.02.03

c语言中/相关合集
c语言中/相关合集

本专题整合了c语言中/的用法、含义解释。阅读专题下面的文章了解更多详细内容。

3

2026.02.03

漫蛙漫画网页版入口与正版在线阅读 漫蛙MANWA官网访问专题
漫蛙漫画网页版入口与正版在线阅读 漫蛙MANWA官网访问专题

本专题围绕漫蛙漫画(Manwa / Manwa2)官网网页版入口进行整理,涵盖漫蛙漫画官方主页访问方式、网页版在线阅读入口、台版正版漫画浏览说明及基础使用指引,帮助用户快速进入漫蛙漫画官网,稳定在线阅读正版漫画内容,避免误入非官方页面。

13

2026.02.03

Yandex官网入口与俄罗斯搜索引擎访问指南 Yandex中文登录与网页版入口
Yandex官网入口与俄罗斯搜索引擎访问指南 Yandex中文登录与网页版入口

本专题汇总了俄罗斯知名搜索引擎 Yandex 的官网入口、免登录访问地址、中文登录方法与网页版使用指南,帮助用户稳定访问 Yandex 官网,并提供一站式入口汇总。无论是登录入口还是在线搜索,用户都能快速获取最新稳定的访问链接与使用指南。

114

2026.02.03

Java 设计模式与重构实践
Java 设计模式与重构实践

本专题专注讲解 Java 中常用的设计模式,包括单例模式、工厂模式、观察者模式、策略模式等,并结合代码重构实践,帮助学习者掌握 如何运用设计模式优化代码结构,提高代码的可读性、可维护性和扩展性。通过具体示例,展示设计模式如何解决实际开发中的复杂问题。

3

2026.02.03

C# 并发与异步编程
C# 并发与异步编程

本专题系统讲解 C# 异步编程与并发控制,重点介绍 async 和 await 关键字、Task 类、线程池管理、并发数据结构、死锁与线程安全问题。通过多个实战项目,帮助学习者掌握 如何在 C# 中编写高效的异步代码,提升应用的并发性能与响应速度。

2

2026.02.03

Python 强化学习与深度Q网络(DQN)
Python 强化学习与深度Q网络(DQN)

本专题深入讲解 Python 在强化学习(Reinforcement Learning)中的应用,重点介绍 深度Q网络(DQN) 及其实现方法,涵盖 Q-learning 算法、深度学习与神经网络的结合、环境模拟与奖励机制设计、探索与利用的平衡等。通过构建一个简单的游戏AI,帮助学习者掌握 如何使用 Python 训练智能体在动态环境中作出决策。

3

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.7万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号