Mỗi ngôn ngữ lập trình đều có cung cấp những kiểu dữ liệu tương ứng. Trong Javascript cũng vậy, chúng ta có hai nhóm lớn là kiểu dữ liệu nguyên thủy và kiểu dữ liệu tham chiếu. Tương ứng chúng ta sẽ có các kiểu dữ liệu nguyên thủy như string
, number
, boolean
, null
, undefined
, symbol
và kiểu dữ liệu tham chiếu như object
, array
, function
. Với mỗi kiểu dữ liệu sẽ có những đặc trưng riêng mà các kiểu khác không có. Vì thế mà nếu chúng ta không kiểm tra kỹ kiểu dữ liệu đầu vào của một hành động nào đó thì có khả năng code của chúng ta sẽ gây bug, thâm chí là làm crash cả hệ thống. Hôm nay chúng ta hãy cùng thử tìm hiểu một số function
trong Javascript nhằm giảm thiểu việc này, giúp chúng ta luôn xác định được chính xác đầu vào của những xử lý của mình.
I. Kiểm tra đầu vào đã được khai báo hay chưa?
Khi chúng ta viết một function dùng để xử lý một công việc nào đó. Việc kiểm tra biến đầu vào của function đã được khai báo hay chưa là một việc thực sự cần thiết. Để khi viết code chúng ta sẽ rẽ nhánh tương ứng cho trường hợp đã được khai báo và chưa được khai báo. Đồng thời khi có những dữ liệu đầu vào bất thường thì xử lý của chúng ta vẫn cho output như mong muốn thay vì gây bug hoặc crash.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <span class="token comment">// Tại đây chúng ta định nghĩa một giá trị là được khai báo khi và chỉ khi</span> <span class="token comment">// giá trị đó khác `undefined` (được khởi tạo nhưng chưa được khai báo giá trị)</span> <span class="token comment">// và `null` (được hiểu là chưa được gán giá trị)</span> <span class="token comment">// Function này sẽ nhận tham số đầu vào là `value`</span> <span class="token comment">// và trả về một giá trị `boolean` cho biết</span> <span class="token comment">// tham số đầu vào `value` đã được khai báo hay chưa</span> <span class="token comment">// `true` => Chưa được khai báo</span> <span class="token comment">// `false` => Đã được khai báo</span> <span class="token keyword">function</span> <span class="token function">isUndefined</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> value <span class="token operator">===</span> <span class="token keyword">undefined</span> <span class="token operator">||</span> value <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token punctuation">}</span> <span class="token comment">// Function này tương tự nhưng ngược lại so với function `isUndefined`</span> <span class="token comment">// Function này cũng nhận tham số đầu vào là `value`</span> <span class="token comment">// và trả về một giá trị `boolean` cho biết</span> <span class="token comment">// tham số đầu vào `value` đã được khai báo hay chưa</span> <span class="token comment">// `true` => Đã được khai báo</span> <span class="token comment">// `false` => Chưa được khai báo</span> <span class="token keyword">function</span> <span class="token function">isDefined</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> value <span class="token operator">!==</span> <span class="token keyword">undefined</span> <span class="token operator">&&</span> value <span class="token operator">!==</span> <span class="token keyword">null</span> <span class="token punctuation">}</span> <span class="token comment">// Ở function này chúng ta sẽ đưa giá trị trả về</span> <span class="token comment">// theo hai hướng là `valid` và `invalid`</span> <span class="token comment">// Nếu `valid` thì sẽ trả về giá trị (hoặc tiếp tục xử lý)</span> <span class="token comment">// Nếu `invalid` thì ngững xử lý và trả về giá trị mặc định (hoặc trả về một cảnh báo)</span> <span class="token keyword">function</span> <span class="token function">greeting</span><span class="token punctuation">(</span><span class="token parameter">message</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> isInvalidMessage <span class="token operator">=</span> <span class="token function">isUndefined</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span> <span class="token comment">// const isValidMessage = isDefined(message)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>isInvalidMessage<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string">'Please define your message before greeting'</span> <span class="token comment">// if (!isValidMessage) return 'Please define your message before greeting'</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Greetings! </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>message<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">}</span> |
Việc kiểm tra việc khai báo của đầu vào sẽ giúp code của chúng ta hoạt động hiệu quả hơn với những trường hợp dữ liệu đầu vào bất thường. Nó còn giúp chúng ta chia xử lý dễ dàng hơn và khả năng xảy ra bug sẽ ít hơn.
Vì vậy chúng ta hãy chú ý kiểm tra kỹ càng việc khai báo đầu vào. Dù rằng chúng ta sẽ code nhiều hơn nhưng nó sẽ tiết kiệm được thời gian điều tra và xử lý bug sau này (nếu xử lý gặp phải bug).
II. Kiểm tra kiểu dữ liệu đúng như mong muốn hay chưa?
Ở phần đầu tiên chúng ta đã có bước kiểm tra việc khai báo. Và nó đem lại hiệu quả cho cho đoạn code của chúng ta, giảm bớt bug cũng như là crash không mong muốn. Nhưng bên cạnh đó khi chúng ta viết một đoạn xử lý đều mong muốn nó hoạt động đúng. Vì vậy việc kiểm tra kiểu dữ liệu của đầu vào cũng là điều tiên quyết cần phải có để xử lý chạy đúng.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <span class="token comment">// Đối với những kiểu nguyên thủy chúng ta sẽ cần dùng `typeof` để kiểm tra</span> <span class="token comment">// string - 'string'</span> <span class="token comment">// number - 'number'</span> <span class="token comment">// symbol - 'symbol'</span> <span class="token comment">// boolean - 'boolean'</span> <span class="token comment">// Đối với những kiểu tham chiếu khi dùng `typeof` kết quả sẽ đều là 'object'</span> <span class="token comment">// ngoại trừ function - 'function'</span> <span class="token comment">// Function này dùng để kiểm tra đầu vào của chúng ta</span> <span class="token comment">// có phải là kiểu nguyên thủy hay không</span> <span class="token comment">// `true` nếu giá trị là một trong 4 kiểu:</span> <span class="token comment">// - `string`</span> <span class="token comment">// - `number`</span> <span class="token comment">// - `boolean`</span> <span class="token comment">// - `symbol` (thường dùng để định danh key trong object)</span> <span class="token comment">// `false` nếu giá trị không thuộc 4 kiểu trên</span> <span class="token comment">// Note: Kiểu dữ liệu `undefined` và `null` sẽ không được đề cập</span> <span class="token comment">// vì 2 kiểu dữ liệu này dùng cho giá trị chưa được khai báo, gán giá trị</span> <span class="token keyword">function</span> <span class="token function">isPrimitive</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token keyword">typeof</span> value <span class="token operator">===</span> <span class="token string">'string'</span> <span class="token operator">||</span> <span class="token keyword">typeof</span> value <span class="token operator">===</span> <span class="token string">'number'</span> <span class="token operator">||</span> <span class="token keyword">typeof</span> value <span class="token operator">===</span> <span class="token string">'symbol'</span> <span class="token operator">||</span> <span class="token keyword">typeof</span> value <span class="token operator">===</span> <span class="token string">'boolean'</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// Function này kiểm tra đầu vào của chúng ta</span> <span class="token comment">// có phải là một object hay không</span> <span class="token comment">// Một giá trị được xem là `object` khi:</span> <span class="token comment">// - Kiểu dữ liệu là object</span> <span class="token comment">// - Và cần được khai báo, gán giá trị</span> <span class="token keyword">function</span> <span class="token function">isObject</span><span class="token punctuation">(</span><span class="token parameter">object</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> object <span class="token operator">!==</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token keyword">typeof</span> object <span class="token operator">===</span> <span class="token string">'object'</span> <span class="token punctuation">}</span> <span class="token comment">// Function này dùng để thêm một cặp `key, value`</span> <span class="token comment">// vào một object vì thế đầu vào `key` sẽ cần là kiểu nguyên thủy.</span> <span class="token comment">// và đầu vào `value` sẽ cần được khai báo giá trị</span> <span class="token keyword">function</span> <span class="token function">addObjectKey</span><span class="token punctuation">(</span><span class="token parameter">object<span class="token punctuation">,</span> key<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">isObject</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token function">isPrimitive</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token function">isDefined</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span> object<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> value <span class="token punctuation">}</span> |
Ở trên là một số function dùng để kiểm tra kiểu dữ liệu nguyên thủy và kiểu tham chiếu (object). Tiếp đến hãy cùng đi thêm một số function kiểm tra kiểu dữ liệu khác.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <span class="token comment">// Khai báo biến `toString` để lưu trữ</span> <span class="token comment">// function `toString` của Object</span> <span class="token comment">// Thường để tránh nhầm lẫn với những `key` khác khi thực thi trong một object</span> <span class="token keyword">const</span> toString <span class="token operator">=</span> <span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>toString<span class="token punctuation">;</span> <span class="token comment">// Function này sẽ trả về chính xác kiểu dữ liệu</span> <span class="token comment">// của một giá trị tham chiếu</span> <span class="token comment">// Ví dụ như `array` khi chúng ta dùng `typeof` thì sẽ là `object`</span> <span class="token comment">// nhưng khi áp dụng function này nó sẽ trả về `Array`</span> <span class="token keyword">function</span> <span class="token function">getRawType</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">toString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// Function này sẽ kiểm tra chặt chẽ hơn</span> <span class="token comment">// việc giá trị đầu vào là một `object` chứ không phải `array`</span> <span class="token comment">// hay là một kiểu dữ liệu like object</span> <span class="token keyword">function</span> <span class="token function">isPlainObject</span> <span class="token punctuation">(</span><span class="token parameter">object</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">getRawType</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">'Object'</span> <span class="token punctuation">}</span> <span class="token comment">// Function này dùng để kiểm tra</span> <span class="token comment">// việc giá trị đầu vào là một biểu thức chính quy `RegExp`</span> <span class="token keyword">function</span> <span class="token function">isRegExp</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">getRawType</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">'RegExp'</span> <span class="token punctuation">}</span> <span class="token comment">// Function này dùng để kiểm tra</span> <span class="token comment">// việc giá trị đầu vào là một `Promise`</span> <span class="token comment">// `Promise` có đặc điểm sẽ có function `then`, `catch`</span> <span class="token keyword">function</span> <span class="token function">isPromise</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token function">isDefined</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token keyword">typeof</span> val<span class="token punctuation">.</span>then <span class="token operator">===</span> <span class="token string">'function'</span> <span class="token operator">&&</span> <span class="token keyword">typeof</span> val<span class="token punctuation">.</span>catch <span class="token operator">===</span> <span class="token string">'function'</span> <span class="token punctuation">)</span> <span class="token comment">// return getRawType(value) === 'Promise'</span> <span class="token punctuation">}</span> |
Chúng ta đã đi qua một số function giúp đảm bảo đầu vào của những xử lý được chính xác nhất, tạo hướng xử lý cho hướng trường hợp bất thường, giảm bug cũng như crash gặp phải.
Những hiệu quả nó mạng lại rất ổn vÌ vậy hãy áp dụng nó vào những đoạn code và kết hợp với Unit test
nó sẽ giúp code của chúng ta được rõ ràng, minh bạch hơn và cover được nhiều nhất có thể các trường hợp bất thường.
III. Kết luận
Vậy là bài viết của mình đến đây là hết rồi. Mong rằng nó dù ít nhưng cũng giúp các bạn một phần nào đó trong quá trình làm việc của mình. Trong bài sau chúng ta sẽ cùng đi đến một số function hữu ích khi làm việc với array cũng như một số thuật toàn thường dùng trong array. Cảm ơn các bạn đã đón đọc. Hẹn gặp lại trong bài viết tiếp theo. Xin chào!!!