JS 大魔王 this

楔子 JS 的 this 通常有所謂的 scope 問題,最近蠻常遇到小夥伴在問,就順便做一下整理,而且通常this會和class一起出現使用。 this 單獨使用 大概有幾種情況 默認綁定(default binding) 在 function 內的 this 為 function 上一層,strict模式為 undefined function main(){ console.log(this) // this = global } main() 隱式綁定(implicit binding) var person = { name: 'ac', getName: function() { console.log(this) // this = person } } person.getName() // 'ac' function click(cb){ cb() } var name = 'aac' click(person.getName) // 把 person.getName 丟到 click 的參數時 // 這時的 this = global,這時 global....

March 30, 2022

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

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

如何在 useEffect 內使用 async function

使用情境 一開始的 API 呼叫把值塞進 React 搜尋 autocomplete 前端一開始開啟都會有呼叫 API 情境的狀況發生,比較基本的方式使用大概會長這樣子。 const Users = () => { const [users, setUsers] = useState([]) useEffect(() => { fetchUsers().then((users) => setUsers(users)) }, []) if (!users) return <div>Loading...</div> return ( <ul> {users.map((user) => ( <li>{user.name}</li> ))} </ul> ) } 那如果要使用 async/await 呢? 很直覺的會這樣寫 // 直接在 useEffect 內使用 async useEffect(async () => { const users = await fetchUsers() setUsers(users) }, []) 但會有一個情況發生,還記的 useEffect 有一個 cleanup function 嗎?...

March 8, 2022

JS 原型說明 by Dan Abramov

楔子 不同的大神針對 JS 有不同的說明講解,來看一下 Redux 作者的說明。 Dan Abramov 有一個 justjavascrpt prototype 其實把觀念寫的蠻好的。 這篇文章是其中一個 prototype 的內容摘錄如下: 先有一個觀念就是 a = '123' 中 a 是變數(variable), 123 是值(value) // teeth 是 variable // 32 是值 let human = { teeth: 32 } let gwen = { age: 19 } human 和 gwen 是一個 Object,他把屬性直接連到 值 // gwen 沒有 teeth 屬性 console.log(gwen.teeth) // undefined let human = { teeth: 32 } 如果當用 __proto__ 在 Object 裡面,=的右邊是一個變數,這是就是去找這個變數的 reference 在哪?...

March 8, 2022