不安裝 npm 套件也可以直接在瀏覽器上生成 UUID!

前言

我們在撰寫文章或簡單的範例時,很常會需要去撰寫一些假資料,而這些假資料通常我們會搭配一個唯一值,也就是所謂的唯一值 key/id,所以這一篇就來介紹一下如何不使用套件就直接產生唯一值 key/id 吧!

唯一值 key/id 是什麼?

唯一值是指在一個集合中,每個元素都是唯一的,也就是說不會有重複的元素存在,而在程式語言中,你可以看到這個唯一值被稱為 keyid(後面統一稱 id)。

有點難懂對吧?我們這邊就想像一個範例,假設我們正在實作一個 TodoList 範本,而每個 Todo 都會有一個唯一的 id,這個 id 就是我們所謂的唯一值,為什麼會需要這個 id 呢?因為我們會透過這個 id 來做一些判斷或操作,例如:刪除、修改等等。

所以 TodoList 這個範例來講,它的範例通常會是一個陣列+物件,因此它的資料可能會長得像這樣:

1
2
3
4
5
6
7
const todos = [
{ id: 1, text: 'Hello World', done: false },
{ id: 2, text: 'Hello JavaScript', done: false },
{ id: 3, text: 'Hello Vue.js', done: false },
{ id: 4, text: 'Hello React.js', done: false },
{ id: 5, text: 'Hello Angular.js', done: false },
];

接著我們就會透過 id 來做一些操作,程式碼可能會長得像這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 刪除特定的 todo
const deleteTodo = (id) => {
const index = todos.findIndex((todo) => todo.id === id);
todos.splice(index, 1);
};

// 修改特定 todo 的文字
const updateTodo = (id, text) => {
const index = todos.findIndex((todo) => todo.id === id);
todos[index].text = text;
};

// 修改特定 todo 的狀態
const toggleTodo = (id) => {
const index = todos.findIndex((todo) => todo.id === id);
todos[index].done = !todos[index].done;
};

因此我們如果想要新增一個 todo 進去 todos 時,就會需要一個唯一值 id,這樣我們才能夠透過這個 id 來做一些操作與處理。

如何產生唯一值 key/id?

那麼我們該如何產生 id 呢?你可能會想說我直接依照陣列的長度來產生 id,這樣應該也可以吧?!

1
2
3
4
5
6
7
8
9
10
11
12
const todos = [
{ id: 1, text: 'Hello World', done: false },
{ id: 2, text: 'Hello JavaScript', done: false },
{ id: 3, text: 'Hello Vue.js', done: false },
{ id: 4, text: 'Hello React.js', done: false },
{ id: 5, text: 'Hello Angular.js', done: false },
];

const addTodo = (text) => {
const id = todos.length + 1;
todos.push({ id, text, done: false });
};

看起來好像沒有問題對吧?但是當你陣列如果有刪除的時候,這樣的方式就會有問題了,因為你的 id 會有重複的情況發生,所以這樣的方式其實是不太安全的。

那麼業界比較常用哪些方式呢?以我知道的部分,比較常見的方式有兩種:

  • 使用 Date.now() 來產生一組 Timestamp 當作 id
  • 使用 Math.random() 來產生一組隨機數當作 id

使用 Date.now()

使用 Date.now() 來產生 id 是一個比較常見的方式,因為它會回傳一個從 1970/01/01 00:00:00 UTC 到目前的毫秒數

1
2
3
4
const addTodo = (text) => {
const id = Date.now();
todos.push({ id, text, done: false });
};

假設傳入 Hello Vue.js,那麼 id 就會是 1714545772080,雖然看起來已經取到毫秒等級,但還是有可能會有重複的情況發生,如果剛剛好有人在同一個毫秒內新增一筆資料,那麼這兩筆資料的 id 就會重複。

使用 Math.random()

Math.random() 雖然是一個隨機數,但是如果直接使用的話,它會是一個浮點數,所以我們可以透過 Math.floor() 來將它轉換成整數,這樣就可以產生一個隨機數當作 id

1
2
3
4
const addTodo = (text) => {
const id = Math.floor(Math.random() * 1000000);
todos.push({ id, text, done: false });
};

但這種狀況下,如果你的 id 是 6 位數,那麼你的 id 就會是 123456 這樣的數字,但如果你的運氣夠好的話,還是有可能會有重複的情況發生。

使用 uuid 來產生唯一值 key/id

難道沒有比較好的方式可以解決嗎?其實有,那麼就是使用一個名為「通用唯一辨識碼(Universally Unique Identifier)」,也就是俗稱的 UUID,那麼 UUID 是什麼呢?這邊我們先不過度深入探討 UUID,只會簡單介紹一下。

簡單來講,UUID 的生成方式幾乎是不可能會有重複的可能性,因為它表現方式如下:

1
cb729eee-87de-4aa8-b455-857bfff869e2

在 UUID 中,它是由 5 組數字與字母組成,每一組之間會以 - 來做區隔,而每一組的長度也是固定的,因此 UUID 是一個非常適合當作 id 的唯一值。

那麼我們該如何在 JavaScript 中使用 UUID 呢?這邊我們可以透過 uuid 這個套件來幫助我們產生 UUID,你只需要透過 npm 來安裝即可:

1
npm install uuid

使用方式也非常簡單,只需要透過 v4() 這個方法即可:

1
2
import { v4 as uuidv4 } from 'uuid';
uuidv4(); // ⇨ 'cb729eee-87de-4aa8-b455-857bfff869e2'

但是問題來了,我們有時候環境只是很單純的 HTML + JavaScript,這時候我們就無法使用 uuid 這個套件了,難道就只能回頭使用 Date.now()Math.random() 了嗎?不,其實現今瀏覽器本身已經有內建 UUID 的功能,使用的方式很簡單,只需要寫 crypto.randomUUID 就可以囉!

1
crypto.randomUUID(); // ⇨ 'cb729eee-87de-4aa8-b455-857bfff869e2'

搭配 addTodo 函式,程式碼可能會長得像這樣:

1
2
3
4
const addTodo = (text) => {
const id = crypto.randomUUID();
todos.push({ id, text, done: false });
};

但是它的支援性如何呢?讓我們來看看 Can I Use:

Can I Use

我們可以看到 crypto.randomUUID 的支援性其實相當高,所以你可以放心的使用它,只是這邊有一個重點在於,crypto.randomUUID 這個方法只能在 HTTPS 的環境下使用,如果你是在 HTTP 的環境下使用,那麼就無法使用哩~

底下我也提供 CodePen 給予參考彼此之間的差異:

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ