日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
JavaScript的死與生

JavaScript 很流行,但它有先天缺陷。Brendan Eich 當(dāng)初只花了10 天時(shí)間就把 JavaScript 設(shè)計(jì)出來(lái)了,作為 JavaScript 之父,BE 如是說(shuō):

與其說(shuō)我愛 JavaScript,不如說(shuō)我恨它。它是 C 語(yǔ)言和 Self 語(yǔ)言一夜情的產(chǎn)物。十八世紀(jì)英國(guó)文學(xué)家約翰遜博士說(shuō)得好:“它的優(yōu)秀之處并非原創(chuàng),它的原創(chuàng)之處并不優(yōu)秀?!?/p>

(摘選自阮一峰的翻譯:JavaScript 誕生記)

JavaScript 的不足,最明顯之處是語(yǔ)法。

糟糕冗長(zhǎng)的語(yǔ)法

可選參數(shù)和默認(rèn)值

 
 
 
  1. function(a, b, option) {  
  2. option = option || {};  
  3. // ...  

上面的代碼中,option 是可選參數(shù),當(dāng)沒(méi)有傳遞時(shí),默認(rèn)值是 {}. 然而,傳遞的 option 值有可能是假值(falsy 值)。嚴(yán)格來(lái)寫,得如下判斷:

 
 
 
  1. function(a, b, option) {  
  2. option = arguments.length > 2 ? option : {};  
  3. // ...  
  4. }  
  5.  

注意:option = typeof option !== 'undefined' ? option : {} 也有可能是錯(cuò)誤的,因?yàn)閭鬟f過(guò)來(lái)的可能就是undefined.

當(dāng)不需要 b 參數(shù),刪除后,基于 arguments.length 的判斷很容易導(dǎo)致忘記修改而出錯(cuò):

 
 
 
  1. function(a, option) {  
  2. option = arguments.length > 2 ? option : {};  
  3. // ...  

如果能增加以下語(yǔ)法該多好呀:

 
 
 
  1. function(a, b, option = {}) {  
  2. // ...  

Let

閉包很強(qiáng)大,也很惱火:

 
 
 
  1. for (var i=0, ilen=elements.length; i   
  2. var element = elements[i];  
  3. LIB_addEventListener(element, 'click', function(event) {  
  4. alert('I was originally number ' + i);  
  5. });  

上面的代碼經(jīng)常在面試題中出現(xiàn),解決辦法是再包裹一層:

 
 
 
  1. for (var i=0, ilen=elements.length; i   
  2. var element = elements[i];  
  3. (function(num) {  
  4. LIB_addEventListener(element, 'click', function(event) {  
  5. alert('I was originally number ' + num);  
  6. });  
  7. }(i));  

如果直接支持 let 語(yǔ)法該多好呀:

 
 
 
  1. for (var i=0, ilen=elements.length; i   
  2. var element = elements[i];  
  3. let (num = i) {  
  4. LIB_addEventListener(element, function(event) {  
  5. alert('I was originally number ' + num);  
  6. });  
  7. };  

模塊

模塊模式是一種無(wú)奈的選擇:

 
 
 
  1. var event = (function() {  
  2.  
  3.   // private variables  
  4.   var listeners = [];  
  5.  
  6.   function addEventListener(f) {  
  7.     listeners.push(f);  
  8.   }  
  9.  
  10.   function clearEventListeners() {  
  11.     listeners = [];  
  12.   }  
  13.  
  14.   // ...  
  15.  
  16.   // export the module's API  
  17.   return {  
  18.     addEventListener: addEventListener,  
  19.     clearEventListeners: clearEventListeners  
  20.     // ...  
  21.  };  
  22. }()); 

如果原生支持該多好呀:

 
 
 
  1. module event {  
  2.  
  3.   // private variables  
  4.   var listeners = [];  
  5.  
  6.   export function addEventListener(f) {  
  7.     listeners.push(f);  
  8.   }  
  9.  
  10.   export function clearEventListeners() {  
  11.      listeners = [];  
  12.   }  
  13.  
  14.   // ...  
  15. }  
  16. (function() {  
  17.  
  18.   import event;  
  19.  
  20.   // ...  
  21. }()); 

繼承

JavaScript 要通過(guò)原型鏈來(lái)實(shí)現(xiàn)繼承:

 
 
 
  1. function Employee(first, last, position) {  
  2.   // call the superclass constructor  
  3.   Person.call(this, first, last);  
  4.   this.position = position;  
  5. };  
  6. // inherit from Person  
  7. Employee.prototype = Object.create(Person.prototype);  
  8. Employee.prototype.constructor = Employee;  
  9.  
  10. // define an overridding toString() method  
  11. Employee.prototype.toString = function() {  
  12.   // call superclass's overridden toString() method  
  13.   return Person.prototype.toString.call(this) +  
  14.          ' is a ' + this.position;  
  15. }; 

如果能寫成下面這樣該多好呀:

 
 
 
  1. class Employee extends Person {  
  2.   constructor(first, last, position) {  
  3.       super(first, last);  
  4.       public position = position;  
  5.   }  
  6.  
  7.   update(camera) {  
  8.       return super.update() + ' is a ' + position;  
  9.   }  

感悟

ECMAScript 委員會(huì)已意識(shí)到 JavaScript 在語(yǔ)法層面上的不足。在 Harmony 規(guī)范中,以上所有語(yǔ)法均已提案。

我們什么時(shí)候才能使用以上語(yǔ)法呢?

只要有宏(Macro)

Lisp 語(yǔ)言的宏特性非常強(qiáng)大。通過(guò)宏,你可以根據(jù)自己的喜好定義想要的語(yǔ)法格式。宏特性使得 Lisp 成為一門“可編程的編程語(yǔ)言(the programmable programming language)”.

JavaScript 沒(méi)有宏。給類 C 語(yǔ)言添加宏特性,目前依舊是個(gè)研究課題,很有難度。

只要有宏,我們就可以自定義語(yǔ)法。但 JavaScript 的宏特性遙遙無(wú)期,還是找找其他路子吧。

Harmony

Harmony 規(guī)范里的語(yǔ)法擴(kuò)展,可能是我們所有人的夢(mèng)。Harmony 有可能成為 ECMAScript 6 規(guī)范。在這之前,我們需要等待,耐心等待。

截止 2011 年 5 月,w3school 顯示 IE6 的市場(chǎng)份額還有 2.4%. Net Market Share 顯示 IE6 占有 10.36% 市場(chǎng)份額。還有 IE7 的市場(chǎng)份額也不少。這些老舊瀏覽器短期內(nèi)不會(huì)退隱市場(chǎng),對(duì)于商業(yè)公司來(lái)說(shuō),比如 Amazon,不可能放棄這批用戶。糟糕的現(xiàn)狀。(中國(guó)大陸更慘,IE6/7 還占有 40% 多市場(chǎng)份額)

我們不能寄期望于“IE 該死”這類呼吁來(lái)讓用戶升級(jí)。聽到過(guò)一種說(shuō)法:IE 用戶僅會(huì)在更換電腦硬件時(shí),才升級(jí)瀏覽器。悲催的是,對(duì)于普通用戶來(lái)說(shuō),收收 email, 上上 Facebook, Twitter, 現(xiàn)有的硬件已足夠。沒(méi)有理由讓他們?nèi)セㄒ还P錢。

Goggle Apps 最近宣布,從 2011 年 8 月開始,將停止支持 IE7.

通過(guò)各種保守估計(jì),Amazon 的網(wǎng)站開發(fā)者,用上 Harmony 語(yǔ)法擴(kuò)展,要一直等到 2023 年!

風(fēng)華正茂的你,愿意等待 10 多年后,再用上這些好用的語(yǔ)法嗎?

#p#

JavaScript 已死

死因:分號(hào)癌。(semicolon cancer. 作者的調(diào)侃,意指語(yǔ)法導(dǎo)致 JavaScript 死去)

通過(guò)上面的分析可以看出,宏特性實(shí)現(xiàn)太難,Harmony 規(guī)范的實(shí)現(xiàn)則遙遙無(wú)期。大量程序員開始書寫 JavaScript, 其中有很多人已經(jīng)厭倦或開始厭倦 JavaScript 冗長(zhǎng)糟糕的語(yǔ)法。我們需要新的語(yǔ)法,我們不想等待!JavaScript,作為源碼編寫語(yǔ)言,已經(jīng)死了!

JavaScript 先生,你曾有過(guò)輝煌的統(tǒng)治。我們與你,有過(guò)甜蜜的回憶,一起產(chǎn)出過(guò)很多有趣的應(yīng)用。祝福逝者安息。

JavaScript 長(zhǎng)存

程序員喜歡掌控自己的命運(yùn)。作為源碼編寫語(yǔ)言,JavaScript 已死。我們可以選擇或創(chuàng)造另一種更好的源碼語(yǔ)言,將其編譯成 ECMAScript 3 的語(yǔ)法格式。

JavaScript 的新生,是作為編譯目標(biāo)(compilation target)。

編譯成 JavaScript 的語(yǔ)言

能編譯成 JavaScript 的語(yǔ)言有很多。我在 1997 年時(shí),收集過(guò)一份列表。包括:

JavaScript 擴(kuò)展語(yǔ)言:已死的 ECMAScript 4, Narrative Script, Objective-J.

已存在的語(yǔ)言:Scheme, Common Lisp, Smalltalk, Ruby, Python, Java, C#, Haskell 等。

還有一些嶄新的語(yǔ)言:HaXe, Milescript, Links, Flapjax, 專門為 web 編程而設(shè)計(jì)。

在這些編譯器項(xiàng)目中,Goggle 的 GWT Java-to-JavaScript 編譯器有可能是最成功的一個(gè)。 然而悲劇的是,現(xiàn)實(shí)項(xiàng)目中,很少看到 GWT 的身影。原因如下:

1. 維護(hù)成本很高。編譯器可能有 bug. 假設(shè)你在一個(gè)大型項(xiàng)目中,發(fā)現(xiàn)了編譯器的一個(gè) bug, 作為維護(hù)者,除了維護(hù)源碼,你還得維護(hù)編譯器。天哪,你有這個(gè)本事嗎?你有這個(gè)本事,CEO 也不愿意花這個(gè)錢呀。

2. 調(diào)試麻煩。Firebug 報(bào)了一個(gè)錯(cuò),報(bào)的是編譯后的行號(hào)。老板站在你背后:趕快啦,小伙子!可是這該死的編譯后代碼,究竟對(duì)應(yīng)哪一行源碼呀?

3. 招聘不到人。假設(shè)你使用 Objective-J 開發(fā)一個(gè)項(xiàng)目,但人手不夠。趕緊招人,HR 說(shuō) 1000 個(gè)人里面,只有 100 個(gè)聽說(shuō)過(guò) Objective-J, 另外 900 個(gè)只聽說(shuō)過(guò) JavaScript. 結(jié)局是你每找一個(gè)新人,都得先培訓(xùn)一把,真是糟糕透頂。

雖然編譯器有以上各種不是,但各種編譯器依舊如雨后春筍大量涌現(xiàn)。毫無(wú)疑問(wèn),編寫 JavaScript 編譯器非??帷=o我報(bào)酬,我也想寫一個(gè)。

在上面的編譯器列表中,有一個(gè)非常有名的引起過(guò)很大轟動(dòng)的:CoffeeScript. 我們來(lái)談?wù)勊?/p>

CoffeeScript

為什么 CoffeeScript 如此火爆?我到現(xiàn)在為止也沒(méi)想明白。是因?yàn)榻o空白賦予了意義,還是帶箭頭的函數(shù)語(yǔ)法?每念及此,我的胃就忍不住波濤洶涌。CoffeeScript 有很多新特性:default parameter values, rest parameters, spread, destructuring,fixing the whole implied global mess… CoffeeScript 很多特性是 Harmony 規(guī)范的一部分,有可能在未來(lái)瀏覽器中直接支持。CoffeeScript 能讓人立刻滿足。

@pyronicide 在 Twitter 上說(shuō):#coffeescript 支持函數(shù)默認(rèn)參數(shù)值,這太令人興奮了。

在 TXJS 2011 大會(huì)上,Douglas Crockford 也表示:CoffeeScript 無(wú)疑是個(gè)好東東。

CoffeeScript: Accelerated JavaScript Development 一書的作者說(shuō):

@trevorburnham

[...] CoffeeScript 不是將 JS 變成 Ruby 或 Python, 而是通過(guò)一套語(yǔ)法,來(lái)更好地發(fā)揮 JavaScript 內(nèi)在的優(yōu)秀。

Douglas Crockford 認(rèn)為 JavaScript 有好的方面,并開發(fā)了 JSLint 工具來(lái)保證開發(fā)者遠(yuǎn)離 JavaScript 中的糟粕。JSLint 允許的語(yǔ)法子集值得擁有自己的名字,我們不妨稱之為 GoodScript.

ECMAScript 5 則引入了 "use strict" 指令來(lái)限制 with 等語(yǔ)法的使用。

CoffeeScript, GoodScript, ECMAScript 5 的目標(biāo)是一致的:遠(yuǎn)離糟粕,同時(shí)提供有用的、安全的語(yǔ)言特性給你。

GoodScript 沒(méi)有提供新特性,ECMAScript 5 的嚴(yán)格模式,大部分瀏覽器還不支持。然而,我們不想等待。

剩下的選擇是 CoffeeScript. 好處:

特別適合 web 開發(fā)。這可能是其他 JavaScript 編譯器沒(méi)做或做得不好的地方。

CoffeeScript 對(duì) JavaScript 的封裝適度。這樣能使得編譯后的代碼比較容易閱讀,調(diào)試也就不那么困難了。

CoffeeScript 看起來(lái)就像是書寫 JavaScript 代碼的一套宏。

CoffeeScript 的編譯器提供客戶端版本。這樣,使用者可以自由選擇,開發(fā)者也可以快速開發(fā)新功能,而不受標(biāo)準(zhǔn)的局限。由社區(qū)的愿景和需求推動(dòng) CoffeeScript 的發(fā)展,這很不錯(cuò)。

發(fā)明自己的語(yǔ)言

你可以去做,這會(huì)是一個(gè)很好的練習(xí)。作為 JavaScript 編譯器的開發(fā)者,將擁有無(wú)上榮耀。

發(fā)明自己的語(yǔ)言,危險(xiǎn)之處在于:你認(rèn)為最終你將比 JavaScript 做得更好。語(yǔ)言設(shè)計(jì)很難,我敢打賭你的語(yǔ)言很難擴(kuò)大市場(chǎng)份額。CoffeeScript 尚未進(jìn)入青春期,就已經(jīng)有抱怨的聲音了。

你可能會(huì)為自己的編譯器能編譯出簡(jiǎn)單、可讀的代碼而驕傲??墒?,一碰到特殊情況,你就會(huì)郁悶得想撞墻。

你的語(yǔ)言里將會(huì)出現(xiàn)慣用法。接著,你馬上會(huì)發(fā)現(xiàn)有人會(huì)破壞這些慣用法(除非你的語(yǔ)言剛好支持宏)。

風(fēng)涼話就不多說(shuō)了。立刻去開發(fā)自己的語(yǔ)言吧,你會(huì)成為一個(gè)很好的程序員。

作為編譯目標(biāo)語(yǔ)言,JavaScript 缺少什么?

作為編譯目標(biāo)語(yǔ)言,JavaScript 重獲新生。在 JSConf.US talk 中,Brendan Eich 表示:Harmony 規(guī)范的目的是讓 JavaScript 成為更好的編譯目標(biāo)。

編譯后的 JavaScript 有可能比手寫的 JavaScript 運(yùn)行效率更低,這就和編譯后的 C 有可能比手寫的匯編語(yǔ)言效率更低一樣。幸運(yùn)的是,JavaScript 的瓶頸主要在 DOM 操作上,語(yǔ)言本身的效率損耗相對(duì)可以接受。雖然話是這么說(shuō),但一些高效的源碼語(yǔ)言編譯后,由于 JavaScript 本身的問(wèn)題,可能極其低效,以致于無(wú)法在真實(shí)環(huán)境中使用。Harmony 規(guī)范中已經(jīng)有部分特性能保證避免這類問(wèn)題。

合理的尾部調(diào)用

 
 
 
  1. function isEven(number) {  
  2.   if (number === 0) {  
  3.       return true;  
  4.   }  
  5.   else {  
  6.       return isOdd(number - 1);  
  7.   }  
  8. }  
  9.  
  10. function isOdd(number) {  
  11.   if (number === 0) {  
  12.       return false;  
  13.   }  
  14.   else {  
  15.       return isEven(number - 1);  
  16.   }  
  17. }  
  18.  
  19. isEven(100000); // InternalError: too much recursion 

上面的代碼,在目前的瀏覽器中運(yùn)行,會(huì)堆棧溢出。

可以通過(guò) 蹦床(trampolines) 技巧來(lái)優(yōu)化:

 
 
 
  1. function bounce(ret) {  
  2.   while (typeof ret === 'function') {  
  3.       ret = ret();  
  4.   }  
  5.   return ret;  
  6. }  
  7.  
  8. function isEven(number) {  
  9.   if (number === 0) {  
  10.       return true;  
  11.   }  
  12.   else {  
  13.       return function() {  
  14.           return isOdd(number - 1);  
  15.       };  
  16.   }  
  17. }  
  18.  
  19. function isOdd(number) {  
  20.   if (number === 0) {  
  21.       return false;  
  22.   }  
  23.   else {  
  24.       return function() {  
  25.           return isEven(number - 1);  
  26.       };  
  27.   }  
  28. }  
  29.  
  30. bounce(function() {return isEven(100000);}); // true 

通過(guò) bounce 方式,在運(yùn)行 isOdd(99999) 時(shí),isEven(100000) 已經(jīng)完成并從堆棧中退出了,因此不會(huì)造成溢出。

幸運(yùn)地是,ECMAScript Harmony 已經(jīng)考慮到了這一點(diǎn),會(huì)自動(dòng)進(jìn)行優(yōu)化。這對(duì)程序開發(fā)者和編譯器開發(fā)者都是有益的。

Lambdas

lambda 并不神奇。簡(jiǎn)言之,lambda 就是可調(diào)用的東西,比如 function, 但需要遵守 TCP(Tennent 一致性原則,Tennent’s Correspondence Principle)。TCP 要求:用一個(gè)緊鄰的 lambda 對(duì)表達(dá)式或代碼塊進(jìn)行封裝,不會(huì)改變被封裝的代碼的含義。

很顯然,JavaScript 的 function 不是 lambda:

 
 
 
  1. function one() {  
  2.   return 1;  
  3. }  
  4.  
  5. one(); // 1 

封裝后,返回值發(fā)生了變化:

 
 
 
  1. function one() {  
  2.   (function() {  
  3.       return 1;  
  4.   }());  
  5. }  
  6.  
  7. one(); // undefined 

對(duì)于接受兩個(gè)參數(shù)并將其求和的代碼塊,lambda 語(yǔ)法提議寫成:{|a, b| a + b}

對(duì)于上面的例子,采用 lambda 封裝將保證返回值和封裝前一樣:

 
 
 
  1. function one() {  
  2.   ({||  
  3.       return 1;  
  4.   }());  
  5. }  
  6.  
  7. one(); // 1 

lambda 塊的稻草人提案目前還沒(méi)有提升到 Harmony 規(guī)范中,讓我們一起努力吧。

瀏覽器缺少什么?

JavaScript 的興衰存亡離不開瀏覽器。JavaScript 的新生,也需要瀏覽器的靠譜支持。

Mozilla 發(fā)起了一個(gè) SourceMap 項(xiàng)目,這可以使得在調(diào)試編譯后的代碼時(shí),能映射回源碼的對(duì)應(yīng)代碼行。這太 cool 了,能極大的減少調(diào)試成本。

聽說(shuō) Webkit 的小伙子們也在干同樣的事情,可惜我找不到任何證據(jù)了-.-

通曉數(shù)種語(yǔ)言

JavaScript 在瀏覽器上的壟斷,意味著前端程序員都會(huì)同一門語(yǔ)言。然而,編譯器的差異性,會(huì)使得 CoffeeScript 程序員,很難立刻看懂基于 Traceur 的 JavaScript 代碼。

這種分歧不可避免。比如有 C, 同時(shí)有 C++ 和 Objective-C 等各種語(yǔ)言。Java 也一樣,基于 JVM 還可以選擇 Clojure 或 JRuby. 微軟意識(shí)到這一點(diǎn),開發(fā)了 CLR. C#, Basic, IronPython 等都可以運(yùn)行在 CLR 上。

前端中的溝通障礙并非新鮮事物。一個(gè) Dojo 程序員,難以立刻明白基于 jQuery 或 YUI 的代碼。

擁有多種源碼書寫語(yǔ)言會(huì)增加社區(qū)的溝通障礙。程序員仍需要了解 JavaScript. 至少一段時(shí)間內(nèi)程序員還需要懂得 JavaScript. 但在短短幾年后,他們可能會(huì)更了解其他源碼語(yǔ)言。

總結(jié)

能有機(jī)會(huì)目睹 JavaScript 的新生,是件很棒的事情。在 JavaScript 編譯的競(jìng)爭(zhēng)中,很難說(shuō)誰(shuí)會(huì)最終贏得市場(chǎng)份額,但毫無(wú)疑問(wèn),這肯定會(huì)很有趣。如今,CoffeeScript 蓄勢(shì)待發(fā),但我相信許多其他成功的源碼語(yǔ)言將接踵而至。

你的想法呢?


分享文章:JavaScript的死與生
轉(zhuǎn)載源于:http://www.dlmjj.cn/article/dhcpioh.html