讓你的JavaScript成為真正的Java Script


  JavaScript為什么叫“JavaScript”?

  要回答這個問題還得從JavaScript的歷史說起。

  1995年5月,Netscape創建了稱為Mocha(摩卡)的瀏覽器端的腳本語言。

  可是沒過多久,同年9月就改名為“LiveScript”。

  又過了沒多久,同年12月,Netscape與sun公司合作,將其改名成“JavaScript”了,意為像Java一樣的Script(腳本語言)。

  為什么最終確定了“JavaScript”這個名字?

  “JavaScript”和“Java”到底有多少相似度呢?

  我們通過幾段代碼來簡單地比較一下~

  既然是“像Java一樣”,那么就以Java為准進行對比。而Java作為一門純正的面向對象的語言(一切皆為對象類),我們就從Java面向對象的3個特性出發進行對比。

  封裝

  封裝作為首要特性,指的是能將對象的屬性或函數隱藏或暴露出來。

  我們創建一個 Animal 對象,讓其有個私有屬性 name ,同時只能通過對象上的 set/get 方法修改/獲取 name 值。

  具體代碼如下:

  // Javaclass Animal { private String name; public void set(String name) { this.name=name;

  } public String get() { return this.name;

  }

  }public class Test { public static void main(String[] args) {

  Animal animal=new Animal();

  animal.set("dog");

  System.out.println(animal.get()); // "dog"

  }

  }// JavaScript(ECMAScript5) function Animal() { var name=''

  this.set=function(a) {

  name=a

  } this.get=function() { return name

  }

  }var animal=new Animal()

  animal.set('dog')console.log(animal.get()) // 'dog'

  對於“封裝”特性,兩者都能實現,但實現方式還是有些區別。

  Java中的類即是對象,用關鍵字 private 和 public 即可達到封裝的效果。

  JavaScript中的作用域為函數,所以需要函數來實現。

  繼承

  Java中的繼承特性可以讓子類獲得父類中定義的屬性和方法。

  class Dog extends Animal {

  public String bark() { return "wang wang wang!!!";

  }

  }

  public class Test {

  public static void main(String[] args) { Dog dog=new Dog();

  dog.set("dog"); System.out.println(dog.get()); // "dog"

  System.out.println(dog.bark()); // "wang wang wang!!!"

  }

  }

  JavaScript中實現繼承得依賴函數中的prototype屬性,將prototype屬性指向父類的實例。

  function Dog() { this.bark=function() { return 'wang wang wang!!!'

  }

  }

  Dogtotype=new Animal()var dog=new Dog()

  dog.set('dog')

  dog.get() // 'dog'dog.bark() // 'wang wang wang!!!'

  在繼承上,JavaScript和Java相比,出現了一些差異:需要在函數聲明之后,讓其prototype屬性指向父類實例以實現繼承的效果,繼承多個父類時還需要將多個實例進行合並。代碼的可維護性和可讀性方面,顯然不Java如在類的聲明時進行定義。

  多態

  多態我們以函數為例,當一個函數需要對不同的輸入結果進行不同的操作時,一般會使用函數重載。下面的例子我們編寫一個 bark 的方法,來針對不同的輸入進行顯示。

  class Cat { // 當輸入字符串時,直接顯示

  public String bark(String sound) { return sound;

  } // 當為輸入時,輸出默認值

  public String bark() { return "...";

  }

  }public class Test { public static void main(String[] args) {

  Cat cat=new Cat();

  System.out.println(cat.bark()); // "..."

  System.out.println(cat.bark("miao~")); // "miao~"

  }

  }

  而JavaScript則比較“悲催”,語言本身不支持重載函數,如果多次定義函數則會被覆蓋,所以只能通過判斷入參來實現多態。

  function Cat() { this.bark=function(sound) { if(undefined !==sound && null !==sound) { return sound

  } else { return '...'

  }

  }

  }var cat=new Cat()console.log(cat.bark()) //'...'console.logcat.bark('miao')) // 'miao'

  在多態這個特性上,JavaScript和Java的區別進一步被放大,因為JavaScript既沒有變量類型聲明,函數也不支持重載。

  更多

  JavaScript和Java的語言差異當然可以列出更多,比如最受人詬病之一的便是JavaScript是弱類型語言,這使得代碼的健壯性下降:函數可能傳入任何可能引起錯誤的值,但是卻只能在執行時發現。當然更高級的接口功能JavaScript原生也是不支持的。

  從上面的代碼分析可以看出,JavaScript和Java還存在着不小的差異,令人欣慰的時ES6版本對JavaScript有不小的提升,讓其更高效和健壯。更令人贊嘆的是Typescript這種膠水語言的出現,讓代碼成為更接近Java的Script。

  我們用Typescript把上面3個類重寫一下:

  // 封裝class Animal { private name:string; public set(name:string):void { this.name=name

  } public get():string { return this.name

  }

  }// 繼承class Dog extends Animal { public bark():string { return 'wang wang wang!!!'

  }

  }// 多態class Cat { public call():string

  public call(sound:string):string

  public call(sound?:string):string { if(undefined !==sound && null !==sound) { return sound

  } else { return '...'

  }

  }

  }

  和Java語言相比,在 封裝 和 繼承 特性上寫法非常相似,有一些小小的差異比如大小寫,類型申明的前后位置,而在 多態 特性上,Typescript增加了類型聲明,但是受限於JavaScript語言限制,只能有一個函數實現,仍然避免不了參數判斷。

  總結

  如果說ES6讓JavaScript更像python,那么Typescript作為ES6的超集,讓JavaScript實至名歸——變得更像Java。

  這樣的好處一方面是讓開發者能寫出健壯、高效的代碼,另一方面是使得JavaSript越來越有可能變成運行在Node.js上的后端語言。對於前端開發者,還是對於JavaScript的全棧開發者來說,都是意義重大的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



猜您在找 如何成為真正的代碼機器的 王陽明:致良知就是讓你成為真正的自己 JavaScript——