← Career advice
Advice Columnist

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為何征服世界的朋友,應該已經知道JavaScript跟TypeScript已經可以在網頁、伺服器、智能電話、IOT、人工智能等範疇落地生根,Dart呢?托Flutter的發展,Dart已相當適合同時於網頁、伺服器、智能電話等範圍作開發,這一點與JavaScript已不相上下。不過Dart與JavaScript的最大分別,在於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.js、index.ts、main.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類別上的欠缺,特意下了不少功夫,也解決了var及let之分,可是相較起來,似乎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就是dart的any吧。

而且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幾乎一模一樣,分別只是先後次序寫法,以及必須寫下傳回值的類別,也就是Future。 Future的概念與JavaScript Promise無任何分別,只是名字上的分別。Java的非同步編程類別,也是稱為Future。

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

 

以下就是JavaScript的版本

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

 

總結

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

文章來源:Tecky Academy – Gordon Lau

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

 

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

 

GetLinks Recruitment

GetLinks Recruitment

GetLinks Recruitment 是一家全方位的人材招募公司。 自2015年以來,我們已經為亞洲超過20,000位人才找到了完美的匹配, 我們的 使命是為求職者和僱主提供一個高效 的 連接平台。 GetLinks Recruitment 迅速成為不少 公司值得信賴的合作夥伴,在全球多個地點設有辦事處,提供一個真正全球化的專業人士和企業網路。

Keep reading

Related career advice

【職場求生術】遇上「扮工」專家?教你4招對付成日扮忙嘅同事
Advice Columnist

【職場求生術】遇上「扮工」專家?教你4招對付成日扮忙嘅同事

喺香港職場,大家一定遇過呢種同事:日日將「好忙啊」、「真係做唔切」掛喺嘴邊,一有新 Task 就即刻卸膊。最令人眼火爆嘅係,佢哋硬係鍾意喺 Weekend 或者半夜三更覆 Email,特登 CC 晒畀班 Management 睇,營造一個「搏命為公司」嘅假象,但實際上工作產出少之又少。 面對呢種「扮工」專家,身為同事嘅你難免會覺得委屈,甚至因為佢推卸責任而增加咗自己嘅 Workload。今次為你準備咗以下 4 招應對策略,教你點樣優雅地應對,唔使硬食死貓! 1. 劃清界線,拒絕無了期「接身後事」 2. 白紙黑字,留低溝通紀錄 3. 唔好做觀眾,冷處理「非辦公時間」嘅表演 4. 專注自己,相信管理層嘅眼光 職場上最重要係保護自己嘅 Mental Health。與其為咗「扮工」同事激心,不如將精力放喺提升自己嘅實力上!

老細每粒鐘要你「報更」?4招教你對付 Micro-management 控制狂上司!
Advice Columnist

老細每粒鐘要你「報更」?4招教你對付 Micro-management 控制狂上司!

返工最怕遇到啲咩?唔係無窮無盡嘅 OT,而係遇到一個 Micro-management(微管理)嘅老細!每日每分每秒都 mon 住你,不停問:「你而家做緊咩?」、「份report搞成點?」,最誇張嘅甚至要你每日 mark 實一張 Time sheet,每個鐘「報更」匯報自己做過啲乜。 面對呢種令人窒息嘅工作環境,與其日日喺位度反白眼兼懷疑人生,不如試下用以下 4 招「反客為主」,拆解老細嘅不安感! 1. 主動出擊:先發制人,塞爆佢個 Inbox 控制狂上司之所以不停問,往往係因為佢缺乏安全感,覺得一切唔喺佢掌握之內。既然佢咁想知,你就不如主動匯報! 2. 善用工具:透明化你嘅工作日程 老細要你每個鐘寫 Time sheet?與其嘥時間填表,不如主動提議用更有效率嘅方法。 3. 向上管理:委婉反映「報更」嘅時間成本 好多老細未必意識到,不停要求員工匯報,其實係會拖慢工作進度。你要搵個適當嘅時機(例如 One-on-one meeting),平心靜氣咁同佢傾下。 4. 建立信任:用實力證明你係「靠得住」 講到尾,Micromanagement 嘅核心問題係「信任」。要老細放手,首先你要證明自己值得被信任。 🌟 終極絕招:三十六計,走為上計! 如果你試過晒以上方法,交足貨又主動溝通,但老細依然故我,將控制慾無限放大,搞到你精神緊張、壓力爆煲……咁證明呢間公司嘅文化根本唔適合你。 與其留喺度受氣,不如及早轉身!全港咁多好老闆,總有一個懂得欣賞你嘅獨立工作能力!唔好等啦,即刻為自己嘅 career 搵條新出路!

【IT事務所】數位經濟與平台經濟:差異與對企業的深遠影響
Advice Columnist

【IT事務所】數位經濟與平台經濟:差異與對企業的深遠影響

在當今快速變遷的科技時代,「數位經濟」(Digital Economy)與「平台經濟」(Platform Economy)是兩個常被交替使用的名詞。然而,兩者在經濟學定義與商業運作邏輯上具有顯著的差異。對於企業而言,理解這些差異不僅是理論上的探討,更是擬定未來發展策略、因應市場挑戰的關鍵。 一、 數位經濟與平台經濟的差異 要釐清兩者的差異,我們可以從「宏觀」的經濟型態與「微觀」的商業模式來進行深入探討。 數位經濟是一個廣泛的總體經濟概念,涵蓋了所有依賴數位科技、數據化資訊與網際網路作為關鍵生產要素的經濟活動。它不僅包括純粹的網路產業,也包含了傳統產業的數位化轉型。只要是運用數位科技來提升效率、創造價值的商業行為與經濟體系,都屬於數位經濟的範疇。例如,一家傳統銀行開發了手機應用程式,讓客戶可以在線上完成轉帳與理財,這種利用數位技術提升營運效率的行為,便是數位經濟的典型展現。 相對而言,平台經濟是數位經濟中一個極具顛覆性的特定商業模式。平台本身通常不直接生產商品或提供實體服務,而是作為一個「中介載體」,利用數位基礎設施來媒合雙邊或多邊市場。在價值創造方式上,數位經濟關注技術如何提升生產力,而平台經濟的核心則在於「降低交易成本」與「創造連結」。延續前述的金融例子,如果一家企業建立的是一個P2P網路借貸平台(如LendingClub),它本身不擁有放貸資金,而是純粹媒合有閒置資金的投資人與需要借款的消費者,這就是平台經濟的運作邏輯。 平台經濟最顯著的特徵是「網路效應」(Network Effects)。在這種模式下,平台的價值會隨著使用者數量的增加而呈指數型成長。以叫車服務平台Uber為例,當平台上的司機越多,乘客的等待時間就越短;乘客體驗變好後,會吸引更多乘客使用,進而又吸引更多司機加入以獲取更高收入。這種跨邊網路效應在一般的數位經濟企業中並不一定存在,卻是平台企業爆發性成長的關鍵引擎。 此外,平台經濟徹底顛覆了傳統的所有權概念,轉向「資產輕量化」與「使用權」的共享。傳統的跨國連鎖飯店如希爾頓(Hilton)或萬豪(Marriott)需要耗費鉅資購買土地、興建飯店並雇用大量員工;然而,Airbnb作為全球最大的住宿提供者,本身卻不擁有一間客房。平台企業藉由調動社會上的閒置資源,以極低的邊際成本進行擴張,這是傳統數位轉型企業難以企及的優勢。 二、 平台經濟對企業的影響 平台經濟的崛起,徹底改變了傳統企業的競爭環境、成本結構與消費者期望。其對企業的影響呈現出強烈的雙面性,既帶來了前所未有的全球化機遇,也伴隨著嚴峻的生存與依賴挑戰。 商業模式的重塑與創新 : 平台經濟迫使傳統企業從「線性價值鏈」(即生產、行銷、銷售給終端消費者)轉型為「生態系統」思維。企業不再只是單純地銷售產品,而是轉向提供服務、體驗,甚至自己轉型為平台。例如,全球知名的農業機械製造商約翰迪爾(John Deere)不再只是一間賣牽引機的公司。他們將設備連上網路,建立了一個農業數據平台,讓農夫、種子供應商與軟體開發者可以在平台上共享天氣、土壤與作物數據,成功從傳統硬體製造商轉型為平台生態系的管理者。 降低市場進入門檻與全球化擴張 : 對於新創公司與中小企業而言,平台經濟大幅降低了接觸消費者的門檻。過去,一個在地工匠或獨立設計師若要將產品賣到國外,需要耗費巨資建立實體通路、尋找代理商或建置昂貴的跨國電商網站。如今,透過如Pinkoi、Etsy或Amazon等大型平台,企業可以「隨插即用」這些現成的數位基礎設施與全球金流、物流系統,迅速將商品賣給全世界的用戶。這種便利性讓企業能將資源集中在產品創新與服務優化上。 競爭加劇與「贏者全拿」效應 : 平台經濟高度依賴數據與網路效應,這極易導致「強者恆強」的局面。當一個平台累積了龐大的用戶基數與數據後,其演算法會變得更精準,進一步形成跨越不過的護城河。例如在搜尋引擎領域的Google,或是社群媒體領域的Meta,因為其龐大的網路效應,後進者幾乎無法撼動其地位。這種「贏者全拿」(Winner-takes-all)或寡占的動態,意味著傳統企業若無法加入主流平台生態圈,或在其中找到無可取代的利基市場,將面臨被邊緣化的巨大風險。 高度的平台依賴風險 : 水能載舟,亦能覆舟。當企業過度依賴單一大型平台時,會喪失對定價、客戶數據以及品牌體驗的控制權。例如,許多餐飲業者高度依賴Foodpanda或UberEats等外送平台來獲取訂單,這不僅意味著必須支付高昂的抽成費用,更代表著他們無法掌握顧客的真實聯絡方式與消費輪廓。同樣地,許多依賴Facebook粉絲專頁獲取流量的新聞媒體與電商,只要平台演算法稍作修改,其觸及率與營收便可能面臨雪崩式的下滑。這種高度的依賴風險,是當代企業在擁抱平台時必須謹慎管理的課題。 數據成為核心競爭資產 : 在平台生態中,數據是最有價值的戰略武器。平台企業透過掌握雙邊用戶的行為數據,能進行極度精準的行銷與產品優化。這種資訊不對稱有時會對依賴平台的企業造成威脅。以Amazon為例,平台上累積了無數第三方賣家的銷售數據;當Amazon發現某款商品極度熱銷時,便可能利用這些數據推出自家的「Amazon Basics」自有品牌產品,以更低的價格與更好的搜尋排名與原本的賣家競爭。因此,傳統企業在利用平台的同時,也必須設法建立自己收集第一手數據(First-party data)的渠道,以維持長期的競爭力。 三、 結論 數位經濟為我們勾勒了技術賦能的廣闊藍圖,而平台經濟則是這幅藍圖中最具爆發力與顛覆性的引擎。透過豐富的實際案例可以看出,面對平台經濟的浪潮,現代企業不能僅僅停留在「將現有業務數位化」的階段。企業必須深入理解多邊市場的運作邏輯與網路效應的威力,思考如何巧妙地融入現有的平台生態系,妥善管理依賴風險,甚至在特定的利基領域中構建屬於自己的微型平台,方能在這場沒有邊界的競爭中立於不敗之地。