首頁  >  文章  >  web前端  >  強型別 JavaScript 的解決方案

強型別 JavaScript 的解決方案

伊谢尔伦
伊谢尔伦原創
2016-11-24 09:35:491089瀏覽

JavaScript 是一種弱型別(或稱為動態型別)語言,即變數的型別是不確定的。

x = 5; // 5
x = x + 'A'; // '5A'

  上面程式碼中,變數x起先是一個數值,後來是一個字串,型別完全由目前的值決定,這就叫弱型別。

  弱類型的好處是十分靈活,可以寫出非常簡潔的程式碼。但是,對於大型專案來說,強類型更有利,可以降低系統的複雜度,在編譯時就發現類型錯誤,減輕程式設計師的負擔。

  一直有人嘗試,讓 JavaScript 變成強型別語言。在官方最終支援強類型之前,本文介紹三種現在就可用的解決方案。

 一、TypeScript

  TypeScript 是微軟2012年推出的一種程式語言,屬於 JavaScript 的超集,可以編譯為 JavaScript 執行。 它的最大特點就是支援強型別和 ES6 Class。

  首先,安裝TypeScript。

$ npm install -g typescript

  然後,為變數指定型別。

// greet.ts
function greet(person: string) {
  console.log("Hello, " + person);
}
greet([0, 1, 2]);

  上面是檔案 greet.ts 的程式碼,後綴名 ts 表示這是 TypeScript 的程式碼。函數 greet 的參數,宣告類型為字串,但在呼叫時,傳入了一個陣列。

  使用 tsc 指令將 ts 文件編譯為 js 文件,就會拋出類型不符的錯誤。

$ tsc greeter.ts
greet.ts(5,9): error TS2345: Argument of type 'number[]'   
is not assignable to parameter of type 'string'.

 二、Flowcheck

  Flowcheck 是一個輕量級的類型斷言庫,可以在運行時(runtime)檢查變數類型是否正確。

  首先,安裝Flowcheck。

$ npm install -g flowcheck

  然後,寫一個宣告了變數類型的腳本。

function sum(a: number, b: number) {
  return a + b;
}
sum('hello','world')

  接著,使用下面的命令,將腳本轉換為正常的 JavaScript 檔案。

$ browserify -t flowcheck -t [reactify --strip-types] \
input.js -o output.js

  轉換後的文件如下。

var _f = require("flowcheck/assert");
function sum(a, b) {
    _f.check(arguments, _f.arguments([_f.number, _f.number]));
  return a + b;
}

  可以看到,程式碼中插入一個斷言函式庫。每次執行函數之前,會先執行斷言,如果類型不符就報錯。

$ node output.js
// throw new TypeError(message);
            ^
TypeError: 
Expected an instance of number got "hello",   
context: arguments / [number, number] / 0
Expected an instance of number got "world",  
context: arguments / [number, number] / 1

 三、Flow

  Flow 是 Facebook 在2014年發布的一個類型檢查工具,用來檢查 React 的源碼。

  安裝指令如下。

$ npm install --global flow-bin

  如果安裝不成功(我就是如此),就需要自己從原始碼編譯了。

  Flow 的用法很多,我只舉幾個例子。前文介紹的兩種工具,只能檢查聲明了類型的變量,而 Flow 可以推斷變量類型。

// hello.js
/* @flow */
function foo(x) {
  return x*10;
}
foo("Hello, world!");

  上面是檔案 hello.js ,該檔案的第一行是註釋,表示需要使用 Flow 檢查變數類型。

$ flow check
hello.js:7:5,19: string
This type is incompatible with
/hello.js:4:10,13: number

  執行 flow check 指令,得到報錯訊息:預期函數 foo 的參數是一個數值,但是實際為一個字串。

  Flow 也支援變數的型別宣告。

/* @flow */
function foo(x: string, y: number): string {
  return x.length * y;
}
foo("Hello", 42);

  另一個有趣的功能是,Flow 可以將類型註解(annotation),轉換為類型宣告。

// annotation.js
/**
  @param {number} x
  @return {number}
 */
function square(x) {
  return x * x;
}
square(5);

  執行 flow port 指令,會得到下面的結果。

$ flow port annotation.js
function square(x: number) : number {
   return x * x;
 }

  Flow 的更多介紹,可以閱讀《Exploring Flow, Facebook's Type Checker for JavaScript》。


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn