JS 其實不是 class 的好朋友

楔子 Coding Style 是一個很有意思的題目,往往不太一樣的 style 就會造成很不一樣的適應,有趣的現象是在 js 環境下,後端很常用 OOP: class style. 但在 React 的環境下就很 function style,但在 angular 的世界內就也是 oop。如果去面式 Node 的後端,如果是 full stack 前端比較熟悉 react 的情況下, 就可能要去準備一下 class style 的 JS/Node。 而在 backend 的夥伴要去應徵 React 的話,就也要熟悉 function style。 tl;dr 一開始入門 js 時,光搞懂這些 this class 的東西應該就飽了,而市面上的書藉也大多數都是先講完這些原理再來開始寫程式,感覺有點反過來了,寫程式總是先可以弄出東西再來慢慢理解為什麼,而一開始的架構沒很大時,光搞抽象弄懂這些額外的「知識」,就搞的暈頭轉向了。 不妨先試著用純 functional 的方式來寫一些東西,慢慢真的熟悉了,發現很多東西都開始好像 code 變的又臭又長時,再來解決這些抽象的東西,反而會比較有感就感。當看了下面一堆 js 的說明,光考就弄倒一堆人了,就自然討厭 js 了,但就算弄懂其實..實務上的差異並不太大,踩到坑再去記住會身體更有感覺。 通常 this 會和 class 一起使用,而其實this就把它當成context(環境參數)來看待就可以了。 Object.create Object.create 就是建立一個 Object 的模版資料,會依 prototype chian 去尋找相關的 method var objTemplate = {name: 'yo'} var childObj = Object....

March 27, 2022

GraphQL Server 方案

楔子 GraphQL Server 的基本架構大概就幾個主要的元件: types 資料結構定義 Server 伺服服務 resolver 資料整理用 模版的東西就拿來改比較快,畢竟自已搞定也要很有愛。 codesandbox 市面上常用的大概就 apollor server,要自已寫 types 和 resolvers。 另一個比較好用的有 prisma ,它本身有包含 database ORM 的功用, 也有自動產出 client 段方便套在自已的前端 web。 雜談 其實在 GraphQL 中,最重要的就是 types & resolvers, 這二個的意函在哪裡? types 其實就想像成資料的欄位設定, resolvers 就想像成取得資料要進行「加減乘除」等等處理的方法。 如果從架構的角度來看 client(Framework) <-> (server <-> database) 在 client 和 server 端為了要彼此能溝通,勢必就要有一個標準的 types 來做依據。 就指的是 client 和 server 端其實都各自要能吃同樣的 types & 解析 query-languages 在 server 端,就因為常常有舊的資料庫問題,那是不是這個 type 同時也能滿足 ORM 的功能? 所以像 prisma 的服務就同時幫你產出 client....

March 23, 2022

graphql use case

楔子 一般傳統的 RESTFul API 通常有一個缺點, 就是要設定不同的路由(routes)來當作入口點, 久而久之就會有一堆的路由網址,也不敢去做任何的修正, 誰敢擔責任改了是不是會噴錯, 慢慢的就也放著讓它愈長愈大了,當然後來有些 library 像 swagger 可以幫助自動產生文件, 但也還是需要做些設定,這也慢慢的讓 graphQL 有開始長大的空間。 GraphQL 主要的精神架構為, Server 設定好條件(資料的格式 schema & 路由 routes), 這時透過查詢語法(Query Language)所帶來的參數,經由 business logic 的轉換(資料 CRUD)再回拋資料。 Server 元件 要架一個 GraphQL Server,思考一下要什麼東西?? 就觀念上就要有三個東西 = Server + 資料格式 Schema + 一些數據的處理 Server: 可以用 ExpressJS,Apollo Server.. graphQL server Scehma: 基本上就是一個定義檔,可以用不同語言的格式 type & schema,應該各語言都有一些轉換方式 logic: 通常就會牽涉到「數據」的處理,就會扯到 DB ,就會有一些 ORM 使用(eg. sequelize, typeorm, prisma..等等) server var express = require('express') var { graphqlHTTP } = require('express-graphql') var { buildSchema } = require('graphql') var schema = buildSchema(` type Query { hello: String } `) var root = { hello: () => 'Hello world!...

March 21, 2022

如何使用 try catch

楔子 寫程式時噴錯誤是蠻常見的,就每發生一個錯誤,再加一個條件去排除錯誤的問題 往往如此, code 就會開始蠻的有點「巢狀」的感覺 if(check) { // 1-level if(check) { // 2-level if(check) { // 3-level } else { // 3-level } } else { // 2-level } } else { // 1-level } 原來的 try-catch 標準的 try-catch 程式長相大概如下, try-catch 主要的功用就是避免程式噴錯跳離 try { // do something } catch (e) { console.log(e.message) } 但也常常有個問題就是錯誤的類型如果不確定,就常常一直補 code 除錯。 所以常常的流程大概就是 包一個 try-catch ,噴錯看 log ,補 if-else 的 bug handling,再重覆 try-catch 的 log.. // version 1 function go(x) { try { let len = x....

March 18, 2022

Box 的好用之處

楔子 程式碼是拿來使用的,今天就來分享一些小工具來幫助寫 code ,這些東西算是函數式編程的入門吧,用久了才會比較有感,今天就當來練練手。 先上個常用的 tool box const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x) const I = x => x const Box = x => ({ chain: f => f(x), map: f => Box(f(x)), fold: f => f(x), inspect: () => `Box(${x})` }) const Right = x => ({ chain : f => f(x), map : f => Right(f(x)), fold : (f, g) => g(x), inspect : () => `Right(${x})` }) const Left = x => ({ chain : f => Left(x), map : f => Left(x), fold : (f, g) => f(x), inspect : () => `Left(${x})` }) const fromNullable = x => (x === null || x === undefined || x....

March 15, 2022

Promise 新手常花時間的坑

楔子 最近有些小夥伴在彼此討論時,常常出現一些不太知道原因,但改一改就好了,就隨手做一下筆記也方便提醒自已。 狀況一: 分不清楚有沒有回傳值 functo go1 () { return 1 } // 有回傳值 functin go2 () { console.log(3) } // 無回傳值 const go3 = () => 2 const go4 = () => { console.log(4) } // 無回傳值 function addOne (x) { return x } const go5 = () => addOne(3) const go6 = () => { 7 } const go7 = (x) => ({x}) 從上面的問題來看,最直覺的就是要有 return 字眼就是代表有回傳值,所以 go1 go2 很容易判斷。...

March 13, 2022

Hight Order Function & Callback Function

楔子 最典型的使用案例是 jQuery 時代,標準的 jQuery 格式大概就長的像下面這樣的格式 // jQuery === $ var hiddenBox = $("#banner-message") jQuery("#button-container button").on("click", function(event) { hiddenBox.show() }) 通常簡化來看就是 $(DOMelement, clickFunction),而 clickFunction 的長相像就也是像 function (event) { // event handling } 如果是把這種格式轉換一下,大概有幾個注意的要點: 參數可以是一個函數 函數以一個參數為佳 function add (x,y) { return x + y } function addFive (x, referenceCallback) { return referenceCallback(x) } addFive(10, add) // 標準化 function highOrderFunction (x, callback) { return callback(x) } 蠻多的 js 的函數也都採用這樣的 coding style。

March 10, 2022

React 設計模式: Compound Components

楔子 摘錄 Kent 的 React Advance Pattern: Compond Components 這個設計模式有什特殊的點? 如果要做一個切換的鈕的元件,大概就會用一個變數來判斷要如何切換? function App() { const [on, setOn] = React.useState(false) return ( <div> { on ? <div>The button is on</div> : null } { on ? null : <div>The button is off</div> } </div> ) } 這樣的 code 就有點醜,那有沒有可能性把 code 長成這樣 ? function App() { return ( <div> <Toggle> <ToggleOn>The button is on</ToggleOn> <ToggleOff>The button is off</ToggleOff> <ToggleButton /> </Toggle> </div> ) } 來完成 Toogle ToogleOn ToogleOff 這三個元件的寫法呢?...

March 10, 2022

取得所有的組合再求結果

使用情境 資料中任二組(或以上)符合某個條件 例如: 想找 [1,2,3,4,5] 任二個值「大於」3有哪些情況 二組資料的「所有組合」想找符合條件的結果 例如: [1,2,3,4] 和 [7,8.9] 的組合中那個「乘」大於 10 上面的情況在整理資料中蠻常發現的,所以手上有這個函數是蠻方便的,也不太需要自已去造輪子刻,拿來用就好了。 這種會分二種情況:第一種是自已資料的展開,第二種是給二個資料組合展開。 Combination const choose = (n, xs) => n < 1 || n > xs .length ? [] : n == 1 ? [...xs .map (x => [x])] : [ ...choose (n - 1, xs .slice (1)) .map (ys => [xs [0], ...ys]), ...choose (n , xs .slice (1)) ] const getCombs = (min, max, xs) => xs ....

March 9, 2022

JS Prototype by Tyler McGinnis

楔子 Tyler 講的 prototype 的觀念蠻清楚 & 簡單的,稍做一下記錄 Tyler McGinnis javascript prototype Prototype is a property of a function that point to an object when function is created. 用下面的例子就可以來解釋上面的句子 function imAFunction () {} imAFunction.prototype // {constructor: f} 把共用的 Method 放在一起包裝在一個 Object 內 // 共用的 method const animalMethods() { eat () {}, sleep () {}, play () {} } function Animal (name, energy) { let animal = Object.crete(animalMethods) animal.name = name animal.energy = energy return animal } 關鍵字 new new 做的就只是把 Object....

March 8, 2022