成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

探討JavaScript:優雅的封裝還是執行效率?

開發 前端
優雅的封裝還是執行效率?這是一個悖論。像C語言和C++之間的差別一樣,JavaScript作為一種解釋性語言,其效率本身就比編譯語言低很多,所以這個問題顯得尤為重要。

優雅封裝的程序看起來是那么的美妙:每個屬性被隱藏在對象之后,你所能看到的就是這個對象讓你看到的,至于它到底是怎么操作的,這個不需要你操心。

執行的效率就是另外一回事。就像是C語言和面向對象的C++之間的差別:C++很優雅,但是執行效率,無論是編譯后的二進制代碼還是運行期的內存的占用,都要比簡單的C語言多出一截來。

這個問題在腳本語言中顯得更加重要,因為JavaScript根本就是一種解釋語言,解釋語言的執行效率要比編譯語言低很多。

1. 優雅的封裝

我們先來看看變量封裝。這里的變量不僅僅是屬性,也包括函數。前面已經說過,JavaScript中并沒有類這個概念,是我們利用變量作用域和閉包“巧妙的模擬”出來的,這是一種優雅的實現。還是溫故一下以前的代碼:

  1. function Person() {     
  2.     var id;     
  3.     var showId = function() {     
  4.         alert("My id is " + id);     
  5.     }     
  6.     this.getId = function() {     
  7.         return id;     
  8.     }     
  9.     this.setId = function(newId) {     
  10.         id = newId;     
  11.     }     
  12. }     
  13. var p = new Person();     
  14. p.setId(1000);     
  15. alert(p.id); // undefined     
  16. // p.showId(); error: function not defined     
  17. var p2 = new Person();     
  18. alert(p.getId == p2.getId); // false    
  19.  
  20. function Person() {  
  21.     var id;  
  22.     var showId = function() {  
  23.         alert("My id is " + id);  
  24.     }  
  25.     this.getId = function() {  
  26.         return id;  
  27.     }  
  28.     this.setId = function(newId) {  
  29.         id = newId;  
  30.     }  
  31. }  
  32. var p = new Person();  
  33. p.setId(1000);  
  34. alert(p.id); // undefined  
  35. // p.showId(); error: function not defined  
  36. var p2 = new Person();  
  37. alert(p.getId == p2.getId); // false  

我們很優雅的實現了私有變量——盡管是投機取巧的實現的。但是,這段代碼又有什么問題呢?為什么兩個對象的函數是不同的呢?

想一下,我們使用變量的作用域模擬出私有變量,用閉包模擬出公有變量,那么,也就是說,實際上每個創建的對象都會有一個相同的代碼的拷貝!不僅僅是那個id,就連那些showId、getId 等函數也會創建多次。注意,考慮到JavaScript函數就是對象,就不會感到那么奇怪了。

但是毫無疑問,這是一種浪費:每個變量所不同的只是自己的數據域,函數代碼都是相同的,因為我們進行的是同一種操作。其他語言一般不會遇到這種問題,因為那些語言的函數和對象的概念是不同的,像Java,每個對象的方法其實指向了同一份代碼的拷貝,而不是每個對象都會有自己的代碼拷貝。

#p#

2. 去看效率

那種封裝雖然優雅,但是很浪費。好在JavaScript是一種靈活的語言,于是,我們馬上想到,把這些函數的指針指向另外的一個函數不就可以了嗎?

  1. function show() {     
  2.     alert("I'm a person.");     
  3. }     
  4. function Person() {     
  5.     this.show = show;     
  6. }     
  7. var p1 = new Person();     
  8. var p2 = new Person();     
  9. alert(p1.show == p2.show); // true    
  10.  
  11. function show() {  
  12.     alert("I'm a person.");  
  13. }  
  14. function Person() {  
  15.     this.show = show;  
  16. }  
  17. var p1 = new Person();  
  18. var p2 = new Person();  
  19. alert(p1.show == p2.show); // true  

這個辦法不錯,解決了我們以前的那個問題:不同的對象共享了一份代碼。但是這種實現雖然有了效率,可是卻太不優雅了——如果有很多類,那么豈不是有很多全局函數?

好在JavaScript中還有一個機制:prototype。還記得這個prototype嗎?每個對象都維護著一個prototype屬性,這些對象的prototype屬性是共享的。那么,我們就可以把函數的定義放到prototype里面,于是,不同的對象不就共享了一份代碼拷貝嗎?事實確實如此:

  1. function Person() {     
  2. }     
  3. Person.prototype.show = function() {     
  4.     alert("I'm a person.");     
  5. }     
  6. var p1 = new Person();     
  7. var p2 = new Person();     
  8. alert(p1.show == p2.show); // true    
  9.  
  10. function Person() {  
  11. }  
  12. Person.prototype.show = function() {  
  13.     alert("I'm a person.");  
  14. }  
  15. var p1 = new Person();  
  16. var p2 = new Person();  
  17. alert(p1.show == p2.show); // true  

不過,這種分開定義看上去很別扭,那么好,為什么不把函數定義也寫到類定義里面呢?

  1. function Person() {        
  2.     Person.prototype.show = function() {        
  3.         alert("I'm a person.");        
  4.     }        
  5. }        
  6. var p1 = new Person();        
  7. var p2 = new Person();        
  8. alert(p1.show == p2.show); // true       
  9.  
  10. function Person() {     
  11.     Person.prototype.show = function() {     
  12.         alert("I'm a person.");     
  13.     }     
  14. }     
  15. var p1 = new Person();     
  16. var p2 = new Person();     
  17. alert(p1.show == p2.show); // true   

實際上這種寫法和上面一種沒有什么不同:唯一的區別就是代碼位置不同。這只是一個“看上去很甜”的語法糖,并沒有實質性差別。

最初,微軟的.Net AJAX框架使用前面的機制模擬了私有變量和函數,這種寫法和C#很相像,十分的優雅。但是,處于效率的緣故,微軟后來把它改成了這種原型的定義方式。雖然這種方式不那么優雅,但是很有效率。

在JavaScript中,這種封裝的優雅和執行的效率之間的矛盾一直存在。現在我們***的解決方案就是把數據定義在類里面,函數定義在類的prototype屬性里面。

原文鏈接:http://devbean.javaeye.com/blog/412296

【編輯推薦】

  1. 淺析Javascript閉包的特性
  2. 提高Web網站性能:JavaScript優化細節
  3. 揭開Javascript閉包的真實面目
  4. JavaScript使用心得匯總:從BOM和DOM談起 
責任編輯:王曉東 來源: JavaEye
相關推薦

2013-04-02 10:10:06

JavaScriptJS

2018-08-03 15:47:00

iOS框架開發

2009-11-27 15:24:48

PHP遞歸效率

2025-04-03 09:27:35

JavaScript開發IIFE

2009-12-01 15:48:12

提高PHP運行效率

2012-07-16 01:20:09

代碼效率

2019-09-20 15:47:24

代碼JavaScript副作用

2021-05-07 06:27:29

JavaScript運算符開發

2024-04-01 13:05:13

C++接口類開發

2021-11-23 10:45:57

StopWatch代碼Java

2011-03-21 15:51:27

SQL執行效率

2023-02-23 19:31:05

Golang函數重載

2024-03-28 14:29:46

JavaScript編程

2024-12-04 15:10:21

2021-07-12 15:35:56

JavaScript代碼運算符

2013-12-17 13:17:25

大數據

2022-03-02 15:31:32

架構網絡請求代碼

2024-07-04 08:02:59

2021-10-25 10:30:12

JavaScript開發 代碼

2022-06-07 08:59:58

hookuseRequestReact 項目
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产一区二区三区欧美 | 日韩精品一区在线 | 国产成人在线播放 | 一二三在线视频 | 丁香婷婷综合激情五月色 | 国产精品毛片久久久久久 | 色婷婷综合成人av | 欧美日韩在线一区二区 | 欧美精品久久久久 | 国产在线视频一区二区 | 久久剧场 | 黑人性hd | 亚洲国产免费 | 精品乱码一区二区 | 欧美日韩国产一区二区三区 | 亚洲一区二区精品 | jlzzjlzz国产精品久久 | 精品国产乱码一区二区三 | 黄视频免费 | 一区二区三区观看视频 | 免费成人高清 | 国产精品久久久久永久免费观看 | 影视一区| 国产在线视频一区 | 日韩一区二区三区视频在线播放 | 91久久精品国产 | 亚州一区二区三区 | 精品国产一区二区三区性色 | 日本亚洲一区二区 | 欧美三级免费观看 | 亚洲人精品午夜 | 激情五月婷婷丁香 | 成人网av | 欧美日韩在线免费观看 | 成人午夜精品 | 久久专区| 成人h电影在线观看 | 国产在线一区二区三区 | 黄色亚洲网站 | 国产精品日产欧美久久久久 | 密色视频 |