← Career advice
Advice Columnist

Dart vs JavaScript vs TypeScript

Dart vs JavaScript vs TypeScript

隨著Flutter受到開發者的重視,Google於2011年推出的Dart又重新進入大家關注的視野之內,不過除了Flutter以外,其實Google的開發者早在2016年也推出過Angular Dart,讓開發者以Dart開發網站應用,不過由於Angular Dart對比TypeScript版Angular文本長期不足,因此沒有引起太多關注。Google推出Flutter,可以說為大家對Dart的信心注入了一劑强心針,大家又重新開始關注這個已有8年歷史的程式語言。

本文想介紹的是,就是到底Dart有何特色?與JavaScript比較,又有何優劣?由於TypeScript開始於前端日漸盛行,我們亦可以趁機比較一下三種語言的異同。

應用範圍(Application)

有讀過上一篇Web Technology為何征服世界的朋友,應該已經知道JavaScriptTypeScript已經可以在網頁、伺服器、智能電話、IOT、人工智能等範疇落地生根,Dart呢?托Flutter的發展,Dart已相當適合同時於網頁、伺服器、智能電話等範圍作開發,這一點與JavaScript已不相上下。不過DartJavaScript的最大分別,在於Dart本身可以有三種方法運行:分別是編譯為JavaScript(Compiled To JavaScript)、由Dart VM獨立運行(Standalone By Dart VM)、AOT編譯為機械碼(Ahead-of-time compiled to machine code). 而JavaScript現時最流行的做法,都是以Node運行JavaScript。Node運行JavaScript時,會將JavaScript轉變為機械碼(Machine Code),再運行機械碼。亦是因此Node JS的運行速度比其他動態語言如Python、Ruby等都較快。而Flutter所採用的,就是第三種方法,先編譯為機械碼(AOT Compilation)再在智能電話運行,因此大家可能聽過Flutter無需JS Bridge的原因,亦是由於早已編譯為機械碼,所以無需一個額外的JS Bridge再作轉譯。

 

React Native寫成的手機程式結構如下:

Flutter寫成的手機程式結講則如下:

基本運行

理解了Dart、JavaScript、TypeScript各自的應用範圍,就以三種語言都寫一個簡單的hello world為例:

JavaScript 和 TypeScript的例子都是:

.
console.log("Hello World");
.

Dart的例子:

.
print("Hello World");
.

要在command line運行,就分別如下面三行:

.
node index.js
ts-node index.ts
dart main.dart
.

以上index.jsindex.tsmain.dart都是進入點(entry point)。 具體分別不大,都是以語言的命令(node,ts-node,dart)直接運行檔案,無須額外編譯,因為Dart受JavaScript 影響很大,想必也從JavaScript汲取了這一點。 順帶一提,JS及TS都支援REPL(Read-Eval-Print-Loop),但Dart無官方REPL,無法像JS及TS一樣於REPL裏面直接嘗試代碼。

 

基本語法

基本語法上,由於Dart受JavaScript影響很大,因此語法上很類似,但與TypeScript比較之下,卻看見了兩者取態的不同。TypeScript受Scala的語法影響,將類別(Type)置於變數及參數之後;相反,Dart則沿用傳統Java及C#的前置類別語法。

由變數及函數一看,就可見不同之處。

 

變數(Variable)

JavaScript例子:

.
var num = 123;
let hello = "Hello Dart!";
const obj = { key1: 1234, key2: 5678};
.

TypeScript例子(例子中類別皆可省略):

.
var num:number = 123;
let hello:string = "Hello Dart!";
const obj:obj = { key1: 1234, key2: 5678};
.

Dart例子:

.
var num = 42;
dynamic hello = "Hello Dart!";
final obj = {"key1":1234,"key":5678};
hello = 1234;
String myName = "Tecky";
const PI = 3.141592654;
var x;// == null
.

JavaScript的例子與TypeScript除了額外的類別,幾乎一模一樣,反之Dart則非常不同,Dart有幾種不同的方法定義變數:

  1. var: 定義一個新的變數,類別由數值所推論,所以如果將num重新賦值為String會出現Error,但賦值為同一類別則無問題。
  2. dynamic: 定義一個新的變數,類別不定,重新賦值任何類別都無問題。
  3. final: 定義一個新的常數,不可重新賦值。
  4. 直接前置類別如String: 定義一個新的變數,類別由前置類別決定,如果將重新賦值為其他類別會出現Error,但賦值為同一類別則無問題
  5. const: 與final類似,編譯常數,不可重新賦值。

可見Dart為了增强JavaScript類別上的欠缺,特意下了不少功夫,也解決了varlet之分,可是相較起來,似乎TypeScript的後置類別更為簡潔。

 

運算符號(Operators)

運算符號上,Dart跟JavaScript及TypeScript都很類似,其中一個最大的分別,在於Dart不支援===,而且在if statement中,必須使用boolean,不可以如JS及TS一樣使用其他數值作boolean使用。

JavaScript 及TypeScript例子:

.
let num = null;
if(!num){
    console.log(`null is false`);
}
let zero = 0;
if(!zero){
    console.log(`zero is false`);
}
.

以上用法在Dart是錯誤。只能使用Boolean作真假判斷 Dart例子:

.
var num = null;
if(num == null){
    print(`null is not false`);
}
var zero = 0;
if(zero == 0){
    print(`zero is not false`);
}

 

函數(Function)

函數方面,Dart不使用關鍵字function,語法較簡潔。

JavaScript例子:

.
function sum(a,b){
    return a + b;
}
.

TypeScript例子(例子中回傳值的類別可省略):

.
function sum(a:number,b:number):number{
    return a + b;
}
.

Dart例子:

.
sum(int a, int b){
  return a+b;
}
.

Dart的例子中,如果不寫int的類別,那兩個參數都會是dynamic 類別,也就是任何類別都可以成為參數。

sum(a,b){
return a+b;
}
// equals to 

sum(dynamic a,dynamic b){
return a+b;
}
.

而如果你寫了

.
sum("1",1);
.

就會出現一個Runtime Exception,也就是與JavaScript類似,失去了類別的保護作用。 似乎dynamic就是dartany吧。

而且dart還有一個特點,就是每個作為進入點的檔案都必須有一個名為main的函數作為進入點,這一點明顯繼承了C的傳統

.
main(){
    sum(2,2);
}

sum(int a, int b){
    return a+b;
}
.

 

進階語法

除了以上基本函數、運算符號、變數的語法之外,Dart作為一種多用途語言,亦同時有類別(Class)的語法及專為非同步編程(Async Programming)而設的語法。

 

類別(Class)

類別是物件導向編程一個重要部份,Dart由JavaScript發展出來,因此類別語法亦與JavaScript非常類似,卻又與TypeScript有些相似。

以下是Dart的類別語法:

.
import 'dart:math';

class Point{
    num x;
    num y;
    num z= 0;

    Point(num x, num y){
        this.x = x;
        this.y = y;
    }

    num distanceTo(Point other) {
        var dx = x - other.x;
        var dy = y - other.y;
        return sqrt(dx * dx + dy * dy);
    }
}

void main(){
    var p1 = Point(2,2);
    var p2 = new Point(4,5);
    p1.distanceTo(p2);
}
.

與JavaScript相當類似,不同在於method 上定義的分別及初始化(initialization)物件不一定需要new keyword.

 

以下是TypeScript同樣的類別語法:

.
class Point{

    private x: number;
    private y: number;
    private z: number = 0;

    constructor(x:number,y:number){
        this.x = x;
        this.y = y;
    }

    distanceTo(Point other){
        let dx = x - other.x;
        let dy = y - other.y;
        return sqrt(dx * dx + dy * dy);
    }
}

const p1 = new Point(2,2);
const p2 = new Point(4,5);
p1.distanceTo(p2);
.

要留意的是,Dart亦不支援Access Modifier,例如上面TypeScript所用的private在Dart裏面不會用到。因此Dart不能像TypeScript一樣,定義private field.

 

非同步編程(Asynchronous Programming)

作為前端開發的程式語言,非同步編程是必不可少的一部份,汲取了JavaScript的教訓,Dart本身就支援了async

Dart的async與JavaScript幾乎一模一樣,分別只是先後次序寫法,以及必須寫下傳回值的類別,也就是FutureFuture的概念與JavaScript Promise無任何分別,只是名字上的分別。Java的非同步編程類別,也是稱為Future

.
Future main() async{
    await someAsyncOperation();
}
.

 

以下就是JavaScript的版本

.
async function main(){
    await someAsyncOperation()
}
.

 

總結

本文總結了一些DartJavaScriptTypeScript的異同,亦因篇幅所限,未能詳盡解釋其他Dart特別用法例如MixinsCallable Classes等。筆者認為Dart明顯是希望改善JavaScript弱類別的缺點而設計,然而Dart卻因為多年的停滯錯過了前端近年的飛速發展,反而被後上的TypeScript超越。程式語言的受歡迎程度,往往可以受一兩個應用範圍所左右:Objective-C一直寂寂無名,因為iOS的發展變得廣受歡迎;RustFirefox自家製程式語言,也因為Firefox新引擎Servo而變得聲名大噪,未知Flutter能否為Dart迎來發展之第二春呢?這就要大家拭目以待了。

文章來源:Tecky Academy – Gordon Lau

呢篇文章係由Tecky Academy提供。如果你中意呢篇文章,您可以喺呢到睇更多佢哋嘅文章。

 

不要讓在亞洲的頂尖科技公司之中工作停留在夢想的階段。在GetLinks創立自己的履歷,並在完成履歷時選擇「我想跨國工作」一欄,今日就向你的夢想踏出第一步吧!

 

Keep reading

Related career advice

【職場心理學】上司話你唔夠狠,下屬話你唔撐佢哋——做中層,你係人肉避雷針
Advice Columnist

【職場心理學】上司話你唔夠狠,下屬話你唔撐佢哋——做中層,你係人肉避雷針

Head count凍結,上司call你入房話:「你自己諗辦法。」 下屬問你年加幾多,你知道答案,但唔敢講。高層宣布新政策,問有冇問題,你笑住話「冇」,但你心裡清楚返去個部門一定炸鍋。績效review,你要寫低屬下嘅不足,但寫嗰陣你係唔舒服嘅,因為佢哋真係有盡力。開完會,上司叫你「帶領好個team嘅方向」,但連你自己都唔知方向係邊。 你夾喺中間,上唔到、落唔得。 高層嫌你執行力唔夠;下屬覺得你唔夠幫佢哋發聲;HR話你要做好榜樣;另一半問你點解又係咁夜返屋企。某一日,你喺東鐵線車廂裡,有個陌生人跟你對眼笑咗一下——你差啲想喊。 有時喺輔導工作中,我遇到嘅中層 manager,坐低嘅第一句往往係:「我唔知自己係咪做錯咗啲乜。」 你以為係你管理技巧唔好?唔係嘅。喺心理學入面,呢個叫「情緒勞動」(Emotional Labor)——即係持續壓抑或管理自己嘅真實情緒,去配合組織對你嘅形象要求(Hochschild, 1983)。做中層嘅人,每日都要演一場無劇本嘅戲:對上管理期望、對下管理情緒、對外管理形象——而你自己嘅感受,係冇位置擺嘅。 長期嘅情緒勞動,係職場 burnout 最常見、又最容易被忽視嘅根源之一。 就好似一架升降機嘅緩衝彈簧——佢嘅功能係吸收衝擊、保護兩邊。但如果長期超重、冇保養,彈簧遲早會斷。 緩衝係你份工嘅一部分,但唔代表你要用自己嘅身心做消耗品。 有一個有用嘅覺察練習:每個星期,寫低三件「唔係我份工、但我一直係咁做緊」嘅事。唔係叫你即刻唔做,而係讓自己知道——你嘅邊界喺邊,你係幾時開始一點一點失去自己嘅。 覺察,係改變嘅第一步。 做中層嘅你,好少被讚,好少有人問你「你點呀」。 今日,我想問你:你點呀? 唔使答得好好聽。只係停一停,不加批判地承認:「係,我最近好攰。」 呢份誠實,係你對自己最大嘅善意。你唔係一個齒輪,你係一個人。 參考資料Hochschild, A. R. (1983). The managed heart: Commercialization of human feeling. University of California Press.Kahn, R. L., et al. (1964). Organizational stress: Studies in role conflict and ambiguity. Wiley.

升職加薪後,為何很多人反而更焦慮?
Advice Columnist

升職加薪後,為何很多人反而更焦慮?

上月專欄談到,在裁員、縮編及經濟不確定性下,職場人士需要建立「財務韌性」,讓自己即使面對收入中斷,仍然保有生活與選擇的空間。 但有趣的是,最近接觸不少客戶時,我發現另一個現象:有些人明明升了職、加了薪,甚至晉升管理層,焦慮感卻沒有減少,反而愈來愈重。 按常理推算,收入增加應該帶來更多安全感,為何現實往往相反?問題很多時不在收入,而在生活模式。 收入增加了,壓力卻沒有減少 曾有一位四十多歲的管理層客戶,十年間薪酬幾乎翻倍,由月入四萬元增至接近八萬元。表面看來事業發展理想,但當我們一起檢視財務狀況時,卻發現他的壓力比十年前更大。 原因很簡單。收入增加後,他換了更大的住宅,供款增加;子女升讀國際學校,教育開支上升;家庭旅遊、保險及生活消費亦同步提高。結果雖然收入增加了一倍,但每月可自由運用的現金流卻沒有明顯改善。 更重要的是,他開始不敢轉工。因為一旦收入出現空檔,整個家庭開支結構都可能受到影響。這種情況在中產及管理層人士之間其實相當普遍。 高收入,不等於高安全感 近年有一個財務規劃概念稱為「生活膨脹」(Lifestyle Inflation),意思是當收入增加時,支出亦同步上升,結果財務自由度未有真正改善。 從職涯管理角度來看,這亦是一種風險。不少人以為職場安全感來自更高薪酬或更高職位,但真正的安全感,很多時來自保留選擇權。 當你有能力拒絕不適合的工作、可以接受短暫轉型期、甚至有空間進修或探索新的職涯方向時,你才真正掌握主動權。相反,如果每月開支已完全依賴當前收入水平,即使職位再高,也可能陷入「不能停、不能轉、不能錯」的壓力循環。 那麼,升職加薪後應如何避免陷入這種情況?我認為有三個值得思考的方向。 第一,讓收入增長快於生活成本增長。 每次加薪後,未必要即時提升所有生活開支。把部分新增收入轉化為儲蓄、投資或退休規劃資產,長遠往往比單純增加消費更有價值。 第二,建立與收入無關的資產。 無論是投資組合、強積金、自願性供款,甚至其他長期資產,本質上都是將今天的工作收入轉化成未來的選擇權。 第三,定期檢視自己的「財務自由度」。 問自己一個簡單問題:如果今天失去工作,現有資源足夠支撐多久?答案未必需要非常充裕,但至少應讓自己擁有重新規劃下一步的時間。 職場發展當然重要,但我認為衡量成功不應只看職位高低或薪酬數字。真正值得追求的,或許不是賺得更多,而是在收入增加的同時,仍然保留選擇人生的能力。因為高薪不一定等於自由,而能夠掌握選擇權的人,往往才擁有真正的安全感。

【IT事務所】駕馭未知的浪潮:企業在持續進化的 AI 時代下的道德標準與管治之道
Advice Columnist

【IT事務所】駕馭未知的浪潮:企業在持續進化的 AI 時代下的道德標準與管治之道

在數位經濟與人工智能技術高速發展的今天,企業正面臨一場前所未有的技術變革。隨著大型語言模型與自主智能體(Agentic AI)的持續進化,企業在享受自動化與生產力提升的同時,也無可避免地遭遇了複雜的道德與管治(Governance)難題。若缺乏完善的監管框架,AI 的失控不僅可能引發公關危機與合規風險,更可能損害企業的長期競爭力。因此,深入理解並建立具備韌性的 AI 管治機制,已成為現代企業不可迴避的戰略核心。 企業在引入 AI 時首當其衝的挑戰便是算法偏見與歧視。AI 模型的輸出品質高度依賴於其訓練數據,若歷史數據本身潛藏社會偏見,AI 系統便會不加思索地放大並延續這些不公。以人力資本管理為例,曾有跨國企業開發 AI 簡歷篩選系統以加速招聘流程,卻發現系統因過去十年的技術職位多由男性擔任,進而「學會」對包含女性特徵詞彙的簡歷給予較低評分。這種情況若發生在銀行或保險業的信貸審批上,將對特定族群造成系統性歧視,進而引發嚴重的合規風險與潛在的金融爭議。 另一個不容忽視的難題是深度學習模型的「黑箱」特質與透明度不足。即使是系統開發者,往往也難以確切解釋 AI 是如何推導出特定結論的。在醫療健康診斷、保險理賠評估或金融爭議處理等需要高度問責與精確性的領域中,這項缺陷尤為致命。若 AI 系統拒絕了客戶的理賠申請或作出了不利的決策,企業卻無法向大眾與監管機構提供清晰的邏輯解釋,這將嚴重摧毀消費者信任。因此,「可解釋性 AI」(Explainable AI)的發展與應用,對於推動技術落地至關重要。此外,在日常營運中,員工若在未經授權的情況下使用面向公眾的生成式 AI 工具,極易在不知不覺中輸入企業機密或客戶的敏感數據,這凸顯了防範數據隱私與商業機密外洩的迫切性。 面對上述挑戰,企業必須摒棄僵化的政策,轉而建立一套動態且跨部門的 AI 管治框架。AI 的應用早已超越單一資訊科技部門的範疇,企業應籌組涵蓋技術、法務、合規、人力資源及業務代表的專責委員會,共同制定符合企業核心價值觀的 AI 使用政策。同時,企業必須實施分級風險評估機制,針對不同應用場景採取差異化管理。例如,用於撰寫一般行銷文案的低風險系統可採常規監管;但涉及客戶信用評分、自動化醫療決策等高風險領域,則必須強制進行嚴格的「偏見審計」,並確保人類在決策流程中保留最終決定權。 在技術部署與企業文化層面,企業應積極引入私有化與企業級的 AI 解決方案,透過安全的隔離環境處理敏感數據,從根本上阻絕資料外洩的風險。然而,技術的防護仍需配合持續的內部審查與教育訓練。由於 AI 模型會隨著時間推移產生「數據漂移」(Data Drift)導致預測失準,企業必須定期對系統進行回溯測試。更重要的是,管治不僅是限制,更是賦能。企業應致力培養全體員工的數位素養,教導他們識別輸入敏感資訊的風險,並學會批判性地評估 AI 生成的結果,而非盲目信賴。 總結而言,在數位轉型的浪潮中,AI 的管治與道德標準絕非阻礙創新的絆腳石,而是企業實現永續發展(Sustainability)的堅實護城河。一間能夠負責任地運用 AI、嚴格保障數據隱私並確保算法公平性的企業,將能在未來競爭激烈的市場中贏得深厚的社會信任與品牌價值。唯有將「道德設計(Ethics by Design)」的理念深深植根於 AI 應用的每一個環節,企業方能在這場持續進化的技術革命中穩健前行。

Dart vs JavaScript vs TypeScript | CPJobs Career Advice