「 Dart Js Ts 」給前端工程師的一張Dart語言入場券

null仔發表於2020-05-10

前言

各位大佬好久不見啊~

啊~好久沒寫文章了,慚愧慚愧。?

小 null 最近跑去寫 Flutter 了 ~

Flutter 使用 Dart 語言進行開發,小 null 在寫 Flutter 的過程中發現 Dart 和 Javascript/Typescript 有些相似之處~

wordclouds
wordclouds

本文分享上圖中這些相似之處,希望能幫助到打算上車的你~

You might already know Dart. - from 10 good reasons to learn Dart

是的,你還沒開始學 Dart,可能就對它很熟悉了。

Dart 的「 前世今生 . 衰落與崛起 」

Dart 語言的誕生

2011 年 9 月,網路上出現了一封標題為"Future of JavaScript"的谷歌內部電子郵件,郵件中表明,由於 Javascript 語言發展緩慢,谷歌內部正在開發一門比 JavaScript 更好的 web 語言。這門新語言的目標是實現 JavaScript 所能實現的一切。它的主要目標是"保持 JavaScript 的動態特性,但要有更好的效能配置檔案,並能適應大型專案的工具"。它還可以交叉編譯成 JavaScript。這種語言作為技術預覽版向更廣泛的世界釋出,並命名為 Dart。 - 引自 《Dart in Action》

2011 年 10 月 10 日的 GOTO 大會上,谷歌的兩位工程師 Lars Bak (V8 JavaScript engine 專案組長..)和 Gilad Bracha (實現定製 Java/JVM 規範,JVM 規範主要貢獻者..) 釋出了"Dart",也驗證了之前 email 傳聞。Dart 是一種全新的程式語言,旨在幫助開發者構建 Web 應用程式。

2011goto
2011goto

對 Dart 語言開發團隊有興趣的話~可戳 ?Dart 語言背後有哪些大牛?

Dart 1.0 《Dart 1.0: A stable SDK for structured web apps》

2013 年 11 月 14 日,谷歌釋出 Dart 1.0 版。Dart 1.0 版本釋出,不但推出了 Dart 語言 1.0 版本而且還推出了相關開源工具箱和配套的編輯器。為了推廣 Dart,Google 在 Chrome 內建了 DartVM 引擎(已在 2015 年移除),彼時 JavaScript 因為 NodeJs 生態的崛起而煥發了第二春,而 Dart 卻不溫不火,且因為其執行效率飽受詬病。

就這樣,Dart 還在 2018 年 "榮獲 20 大糟糕語言榜首",總結 「 Javascript 很"忙",Dart 很"慘" 」。

2018-worst-lang
2018-worst-lang

Dart 2.0 《Announcing Dart 2 Stable and the Dart Web Platform》

2018 年 8 月 8 日,谷歌釋出 Dart2.0 版本。谷歌對 Dart 進行全新改版,從底層重構了 Dart 語言,加入了很多面向未來的新特性,語言效能大幅提供。Dart 開發團隊總結了 Dart1.0 版本的優缺點,決定打造一個執行更快、更加安全的強型別語言 Dart2.0(在 Dart2.0 之前,Dart 是一門弱型別語言。此次釋出谷歌不僅釋出了 Dart 2.0 穩定版,而且還重寫了 Dart web platform。新版的 web platform 提供了一套高效能、可擴充套件的生產力工具。

Flutter 釋出 《Flutter 1.0: Google’s Portable UI Toolkit》

Google 內部用 Dart 編寫孵化了一個移動開發框架 Sky,之後又被命名為 Flutter,進入了移動跨平臺開發的領域。

2018 年 12 月 4 日,谷歌釋出 Flutter 1.0 版本。

Flutter 是谷歌開源的移動應用開發 SDK,使用 Flutter 可以直接開發 Android 和 iOS 應用。其最大的特點就是一套程式碼多平臺執行、高效能和 Hot Reload(熱過載)。谷歌即將釋出 Fuchsia 系統就以 Flutter 為主要開發框架。Flutter 採用 Dart 作為其底層語言。Dart 也由於 Flutter 美好未來而得到眾多開發者的青睞。

Fuchsia 技術選型,Dart 笑到最後

Android 和 Chrome OS 可能是谷歌最知名的 OS 專案,但實際上這兩年曝光量逐漸增大的是谷歌正在開發的第三個作業系統——Fuchsia。Fuchsia 是一個開源專案,類似於 AOSP(Android 開放原始碼專案),但 Fuchsia 可以執行各種裝置,從智慧家居裝置到膝上型電腦和手機等等。它也被認為是建立在一個谷歌構建的名為“zircon”的全新核心之上,而不是構成 Android 和 Chrome 作業系統基礎的 Linux 核心。

近日谷歌 Fuchsia 網站上更新了一則“Fuchsia Programming Language Policy”的文件,詳細解釋了 Fuchsia 專案在程式語言方面的選型考慮。據官方文件披露,C/C++、Dart、Rust、Go 語言都是 Fuchsia 開發的候選語言,除了老牌程式語言 C 和 C++ 的江湖地位穩固得到了官方開發人員的認可以外,新興程式語言中,Dart 擊敗了 Rust 和 Go 語言,成為使用者 UI 介面的正式官方語言。

Javascript ? Dart

變數宣告

// javascript

var name = 'null仔'

// dart

var name = 'null仔'
複製程式碼

與 Javascript 一樣,在 Dart 中,我們可以使用 var 定義變數。

不一樣的是,在 Dart 中,變數都是引用型別,也就是說所有的變數都是物件,所以 Dart 是一門完全物件導向的語言。

Dart 是型別安全的,所以當你使用 var 關鍵字定義變數時,本質其實就是具體型別的引用。

比如上文程式碼其實就是一個 String 型別物件的引用,這個物件的內容是 null 仔 。

在 Dart 中,宣告一個未初始化的變數,變數的型別可以更改,它的初始值是 null。

variable
variable

在 Dart 中,宣告一個初始化的變數,變數型別不能再更改 。

variable
variable

常量宣告

// javascript

const name = 'null仔';

// dart

const name = 'null仔';
複製程式碼

與 Javascript 一樣,在 Dart 中,我們可以使用 const 定義常量。

Dart 中,還可以使用 final 定義常量,由於本文主要將與 Javascript 的相似點,這裡就不細說了。

constant
constant

模版字串

// javascript

const name = 'null仔';

const word = `My name is ${name}`;

// dart

const name = 'null仔';

const word = 'My name is $name';
複製程式碼

與 Javascript 一樣,Dart 同樣支援模板字串,語法為:varibale。

如果表示式的結果是一個物件,那麼會呼叫物件的 toString()方法。

template-string
template-string

箭頭函式

// javascript

  const getName = (name) => name;

  getName('null仔');

// dart

  String getName(name) => name;

  getName('null仔');
複製程式碼

與 Javascript 一樣,Dart 同樣支援箭頭函式,如果函式只包含一個表示式,可以使用箭頭表示式方法進行簡寫。=> 後面的表示式將作為函式的返回結果。

擴充套件運算子 (Spread Operator)

// javascript

  const list=[1,2,3,4,5];

  [0,...list,6];

// dart

  const list=[1,2,3,4,5];

  [0,...list,6];
複製程式碼

Dart v2.3 引入了 Spread Operator,我們在 Javascript 中很喜歡用的神器,在 Dart 中也可以用啦~嗯,真香~

spread
spread

引數預設值與可選引數

// javascript

  function getInfo({name='null仔',age}){
    console.log(`大家好,我是${name},今年${age}歲`);
  }
  getInfo({age:18});

// dart

  void getInfo({name="null仔",age}){
    print('大家好,我是$name,今年$age歲');
  }
  getInfo(age:18);
複製程式碼

與 Javascript 相似,Dart 支援函式引數預設值與可選引數,Get it ~

default
default

async/await 函式

// javascript

  async function getData(){

    const name= await new Promise((resolve)=>setTimeout(()=>resolve('null仔'),1000));

    console.log(name);  // null仔
  }
  getData();

// dart

  Future getData() async{

    String name =  await Future.delayed(Duration(seconds: 1),()=>'null仔');

    print(name);  // null仔
  }
  getData();
複製程式碼

與 Javascript 相同,Dart 也提供了 async/await 語法糖,讓我們更好的處理非同步操作~

Javascript async 函式返回的是 Promise 物件,而 Dart async 函式返回的是 Future 物件~

async
async

級聯函式(鏈式呼叫)

// javascript

new Promise((r) => {
  r(1)
})
  .then((res) => ++res)
  .then((res) => ++res)
  .then((res) => console.log(++res)) // 4

// dart

 List<int> list =

   []..addAll([1,2,3,4,5])
     ..replaceRange(0,1,[6])
     ..sort((a,b)=>a-b);

  print(list);  // [2, 3, 4, 5, 6]
複製程式碼

在 Javascript 中 我們一般通過手動 "return this" 來實現鏈式呼叫,而 Dart 提供了 Cascade (級聯運算子) .. 幫我們實現鏈式呼叫~ 真香!

Cascade
Cascade

模組匯入和匯出 import

Javascript 和 Dart 都使用 import 來匯入模組,不過不同的是,Dart 並不需要使用 export 來匯出模組。

// 完全匯入

// javascript

import abc from "abc";
import * as xx from "abc";

// dart

import 'package:abc/abc';

// 部分匯入

// javascript

import { xx } from "abc";

// dart

import 'package:abc/abc' show xxx; // 只匯出其中一個物件/方法 xxx
import 'package:abc/abc' hide xxx; // 匯出模組時不匯出xxx
複製程式碼

類 class

//javascript

class Person{
  // 私有屬性提案
  #age=0;
  // 建構函式及引數預設值
  constructor(name='null仔'){
    this.name=name;
  }
  // 例項方法
  getName(){
    console.log(this.name);
  }
  // 靜態方法
  static say(){
    console.log(`hello world`);
  }
  // getter && setter
  get age(){
    return this.#age;
  }
  set age(value){
    this.#age=value;
  }
}

//dart

class Person{
  // 私有屬性
  int _age;
  String name;
   // 建構函式及引數預設值
  Person({this.name='null仔'});
   // 例項方法
  void getName(){
    print(this.name);
  }
   // 靜態方法
  static say(){
    print("hello world");
  }
  // getter && setter
  int get age =>this._age;
  set age(int value)=>this._age=value;
}
複製程式碼
fx
fx

Typescript ? Dart

泛型

Typescript 與 Dart 中都存在泛型,下面我們以一個簡單的泛型函式簡單介紹下~

// typescript

  function identity<T>(arg: T): T {
    return arg;
  };

  identity<String>('null仔'); // null仔

  identity<Number>(18); // 18

// dart

  T identity<T>(T arg){
    return arg;
  }

  identity<String>('null仔'); // null仔

  identity<int>(18);  // 18
複製程式碼
fx
fx

Typescript Type Assertion ? Dart as 運算子

型別斷言(Type Assertion)可以用來手動指定一個值的型別。

值 as 型別
複製程式碼
as-dart
as-dart
as
as

Typescript Optional Chaining ? Dart ?. 運算子

TypeScript 3.7 實現了呼聲最高的 ECMAScript 功能之一:可選鏈(Optional Chaining)!

終於不用再寫 一坨長長臭臭的&& 運算子執行中間屬性檢查 和 null/undefined 判斷了~

// before
if (foo && foo.bar && foo.bar.baz) {
  // ...
}
// after

if (foo?.bar?.baz) {
  // ...
}
複製程式碼

Dart 提供了?.運算子,我們來瞧瞧~

// typescript

let foo;

console.log(foo?.bar?.baz);


// dart

var foo;

print(foo?.bar?.baz);
複製程式碼
optional-chaining
optional-chaining

Typescript Nullish Coalescing ? Dart ?? 運算子

TypeScript 3.7 實現了另一個即將推出的 ECMAScript 功能是 空值合併運算子(nullish coalescing operator)!

?? 運算子可以在處理 null 或 undefined 時“回退”到一個預設值上 !

// typescript

let x = foo ?? bar()

// 等價於

let x = foo !== null && foo !== void 0 ? foo : bar()
複製程式碼

Dart 提供了??運算子,我們來瞧瞧~

// typescript
  let age;

  function setAge() {
    age = 18;
  }

  age ?? setAge();

  console.log(age) // 18

// dart

  var age;

  void setAge() {
    age = 18;
  }

  age ?? setAge();

  print(age); // 18
複製程式碼
nullish coalescing
nullish coalescing

參考

Dart 語言的前世今生

後記

如果你和我一樣喜歡前端,也愛動手摺騰,歡迎關注我一起玩耍啊~ ❤️

github 地址,歡迎 follow 哦~

部落格

我的部落格,點 star,不迷路~

公眾號

前端時刻

前端時刻
前端時刻

相關文章