小熊泡泡

          常用鏈接

          統計

          最新評論

          每個Web開發者應該深諳的JavaScript規則(轉載)

          alex此舉是為了給自己即將出版的新書做個預告,但短短幾句總結性的稱述提煉出了JavaScript的核心設計概念及編程思想,不可謂不精粹。當我看到這幾句話時,暗下思考,再查查犀牛書,才知道自詡精通js的我其實尚是一知半解。以下便來談談我對這幾句話的重新認識:

          • JavaScript里一切皆是對象,包括函數。(Everything in JavaScript is an Object. Even functions)
          "一切皆是對象"是一個詭辯的句子,從不同的角度此句可有不同的解釋。所以java也號稱是完全面向對象的語言。但是我以為alex這里所指的并非語義上的理解,而是從語法的角度。所以這一句應該理解為—— 在JavaScript語言中,操作的一切都是對象。

          我原來以為JavaScript 既然名為 (Java)Script,自然也是繼承Java語言的設計————在Java中,數據類型分為基本數據類型(number,boolean,char等)和對象數據類型————而其實JavaScript所操作的數據類型都是對象,類似于Ruby。怎么理解呢? 例如,整型和布爾值在Java代碼中是一個基本數據類型,它是沒有方法和屬性的,在JavaScript中是怎樣呢? 看如下的代碼:

          //畫蛇添足的方法,僅作為example
          Number.prototype.abs = function() {
              returnMath.abs(this); 
          }
          alert((-100).abs());  // 彈出返回值 100
          Boolean.prototype.reverse = function() {
              return !this;
          }
          alert(true.reverse());  // 彈出返回值 false
          所以, "-100" 和 "true" 在JavaScript中竟然是作為對象來處理的,JavaScript代碼中出現的所謂基本數據類型其實都是其Wrapper對象(Number, Boolean等)的直接量,JavaScript在處理它們時實際上是在操作它們的Wrapper對象。從語法上來說,JavaScript是比Java更面向對象的語言。

          alex更強調在JavaScript中函數也是對象,這是動態腳本語言的重要特性(作為對比,在Java中函數(方法)只是一種語法)。函數成為一個對象,所以函數完全可以看作數據:賦給變量、設為對象的屬性、甚至作為其他函數的參數。函數是對象帶來了巨大的靈活性,也是JavaScript面向對象編程的設計核心之一。當然與之而來的復雜性,也讓JavaScript倍受誤解。

          • 所有對象都是可變的。(Every object is always mutable )
          此句還好理解,因為JavaScript中雖然有 final 保留字,但并沒有提供語法上的實現。所以JavaScript中無法定義一個變量是不可變的。另外一個重要理解就是,JavaScript的對象在創建后可以隨意添加或刪除屬性和方法。
          • "." 操作符等同于"[]"操作符。(The dot operator is equivalent to de-referencing by hash (e.g., foo.bar === foo["bar"]) )
          此句也是針對JavaScript的對象而言。對象的屬性可以用"."加標識符"bar"來存取,也可以使用"[]"配合標識符的字符串形式來存取。這樣就給存取對象屬性帶來了靈活性————可以動態構造一個字符串并以它來存取對象的屬性。此句也揭示了:在JavaScript中數組就是對象,對象本質上就是一個關聯數組。
          • new 關鍵字實際上是先創建一個對象,再讓構造器方法在該對象域中執行。The new keyword creates an object that class constructors run inside of, thereby imprinting them
          此句有些難理解,以一個簡單的構造器函數舉例:
          function Dog(name) {
          	this.name = name;
          }
          var dog = new Dog("小明");

          我以我的理解模擬 new 操作符的執行步驟:

          var dog = newObject(); //首先創建一個新的Object對象
          dog.prototype = Dog.prototype; // 設置構造器函數的原型對象為 dog 的原型對象
          Dog.apply(dog, argumens);  //將新對象傳遞給構造函數,此時構造函數可以用this來初始化新對象

          所以 javascript 并非象java/C++的構造器函數那樣,先執行然后返回一個對象。而是先創建一個未定義屬性的干凈的Object對象,接著把構造器函數的原型對象設置為新對象的原型對象(構造器函數的原型對象是JavaScript自動為每個函數創建的)。最后再把這個對象交給構造器函數,在構造器函數中設置該對象其他的屬性和方法等等。

          通過這樣的方式帶來的巨大動態特性就是, 可以象操作普通函數一樣操作構造器函數。__所有自定義的對象甚至可以使用同一個構造器函數__ 。實際上這也是Prototype和Dojo的核心設計思想。通過這樣的方式和原型對象的設計,JavaScript實現了與Java完全不同的面向對象設計。

          • 所有函數都是閉句。(Functions are always closures (combine w/ previous rule to create OOP) )
          閉句在我的理解中就是函數和其定義時的上下文快照(作用域)關聯在一起。然后函數執行的時候,所有變量都在快照中獲取。犀牛書上的專業闡述是這樣的:
          閉包是一個把函數定義和作用域聯合在一起的對象...執行函數時使用的是在定義它們時就有效的作用域鏈,而不是在執行它們時才有效的作用域鏈...實際上所有函數都是閉包實現的…

          順從這樣的理解:任何函數都有作用域,客戶端編程中頂層的全局域函數也是有作用域的,那就是window對象,所以全局函數也就是全局域和函數定義組合的閉包。

          Alex說此句是JavaScript面向對象編程的重要規則,我就還不能完全參透了。暫時的理解就是如下代碼所示:

          function Dog(name) {
              var name = name;
              function getName() {
                  return name;
              }
              this.getName = getName;
          }
          var dog = new Dog("小明");
          alert(dog.name);  // 彈出"undefined"
          alert(dog.getName()); // 彈出"小明"
          以上代碼中閉句的作用就是讓 name 成為了Dog的私有屬性,只能通過指定的 getName 方法去獲取name。類似于 Java 的 JavaBean。
          • this關鍵字關聯于執行時的作用域,而非定義時的作用域。(The this keyword is relative to the execution context, not the declaration context )
          此句似乎和上句關于”函數是閉包“的描述相反。但確是好理解的,一個函數中如果出現 this 關鍵字,那么這個 this 引用的對象就是調用這個函數的對象。也可以通過JavaScript中函數對象提供的apply和call方法來指定 this 引用的對象。這樣的設計使得一個函數可以被分配給很多對象作為其方法,大大提高了復用性。Prototype中的bind方法及Dojo的dojo.lang.hitch方法都是利用了此規則。
          • 原型對象的屬性也是可變的(The prototype property is mutable )
          此句算是對第二句的補充,JavaScript中每個對象類型(就是構造器函數)都有原型對象,我們可以在任何時候任意改變原型對象的屬性,而且這個改變將影響已經通過new操作符實例化的對象和將來會實例化的對象。

          我要感謝這篇短文,它促使我又認真的讀了一遍犀牛書的相關章節,同時也有了新的認識和心得。感受正如alex最后所說:

          If all of that makes sense to you, JavaScript can be a fun, liberating experience. If not, it’s going to be a world of pain and broken expectations as you shed the baggage of less dynamic languages.

          posted on 2006-07-09 17:58 小熊泡泡 閱讀(210) 評論(0)  編輯  收藏 所屬分類: Javascript

          主站蜘蛛池模板: 平顶山市| 昌宁县| 莒南县| 永年县| 东乡| 稻城县| 藁城市| 安乡县| 册亨县| 邮箱| 孟村| 疏勒县| 广平县| 农安县| 馆陶县| 玉龙| 甘孜| 乃东县| 临朐县| 三门县| 长宁区| 柞水县| 浦县| 正镶白旗| 晋州市| 宜州市| 扎兰屯市| 甘肃省| 武义县| 华宁县| 泰和县| 正安县| 长阳| 五河县| 三亚市| 昌都县| 九龙城区| 铜鼓县| 祁东县| 新田县| 西平县|